2015-07-14 41 views
7

Ho fatto questo esempio qui: http://jsbin.com/pokahec/edit?html,outputVimeo iFrame Rubare rotellina del mouse Event su Firefox

// creates a global "addWheelListener" method 
// example: addWheelListener(elem, function(e) { console.log(e.deltaY); e.preventDefault(); }); 
(function(window,document) { 

var prefix = "", _addEventListener, onwheel, support; 

// detect event model 
if (window.addEventListener) { 
    _addEventListener = "addEventListener"; 
} else { 
    _addEventListener = "attachEvent"; 
    prefix = "on"; 
} 

// detect available wheel event 
support = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel" 
      document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel" 
      "DOMMouseScroll"; // let's assume that remaining browsers are older Firefox 

window.addWheelListener = function(elem, callback, useCapture) { 
    _addWheelListener(elem, support, callback, useCapture); 

    // handle MozMousePixelScroll in older Firefox 
    if(support == "DOMMouseScroll") { 
     _addWheelListener(elem, "MozMousePixelScroll", callback, useCapture); 
    } 
}; 

function _addWheelListener(elem, eventName, callback, useCapture) { 
    elem[ _addEventListener ](prefix + eventName, support == "wheel" ? callback : function(originalEvent) { 
     !originalEvent && (originalEvent = window.event); 

     // create a normalized event object 
     var event = { 
      // keep a ref to the original event object 
      originalEvent: originalEvent, 
      target: originalEvent.target || originalEvent.srcElement, 
      type: "wheel", 
      deltaMode: originalEvent.type == "MozMousePixelScroll" ? 0 : 1, 
      deltaX: 0, 
      deltaZ: 0, 
      preventDefault: function() { 
       originalEvent.preventDefault ? 
        originalEvent.preventDefault() : 
        originalEvent.returnValue = false; 
      } 
     }; 

     // calculate deltaY (and deltaX) according to the event 
     if (support == "mousewheel") { 
      event.deltaY = - 1/40 * originalEvent.wheelDelta; 
      // Webkit also support wheelDeltaX 
      originalEvent.wheelDeltaX && (event.deltaX = - 1/40 * originalEvent.wheelDeltaX); 
     } else { 
      event.deltaY = originalEvent.detail; 
     } 

     // it's time to fire the callback 
     return callback(event); 

    }, useCapture || false); 
} 

}) (finestra, documento);

È possibile verificare in Firefox che scorrere evento viene generato, ad eccezione di quando sopra vimeo iframe (e credo che qualsiasi iFrame)

C'è qualche soluzione al fuoco evento su iframe?

PS - Voglio utilizzare questo in una barra di scorrimento personalizzato

risposta

6

Questo è fondamentalmente in base alla progettazione. Il tuo codice dovrebbe essere completamente inconsapevole di ciò che l'utente fa all'interno di un IFRAME (specialmente uno da un'origine diversa come YouTube - questa è una parte dell'architettura di sicurezza del web, come richiesto dalla stessa politica di origine.)

Ora, anche nel caso di cross-origine i browser possono scegliere di lasciare che lo scrolling abbia effetto sull'antenato del frame se il frame stesso non scorre. Questo scorrimento deve avvenire senza alcun evento che sparano sul documento top - vedere il comportamento di Chrome se si scorre verso il basso di questo IFRAME e mantenere lo scorrimento: http://jsfiddle.net/8cj0dofx/1/ HTML:

<iframe src="data:text/html,<body style='background:grey;height:550px'>Hello" seamless></iframe> 
<div style="height:100px">Hello</div> 

JS:

document.addEventListener('DOMMouseScroll', function(e){ 
    document.getElementsByTagName('div')[0].firstChild.data += ' ' + e.type 
}); 

document.addEventListener('mousewheel', function(e){ 
    document.getElementsByTagName('div')[0].firstChild.data += ' ' + e.type 
}); 

Quello che vedrete è che quando si scorre alla fine dell'IFRAME, il documento principale scorrerà ma nessun evento si attiverà fino a quando il mouse si trova sopra il documento principale.

+0

quindi non è possibile l'hacking? – digitalzoomstudio

+1

Beh, suppongo che potresti mettere un DIV trasparente sopra l'IFRAME - ma il tuo visitatore probabilmente perderà la possibilità di riprodurre/mettere in pausa il video. – hallvors

+0

Inoltre, se si aggiunge un attributo "scrolling = no" all'IFRAME, il browser non scorrerà i contenuti IFRAME separatamente.Non sono sicuro se questo aiuti il ​​tuo caso d'uso - la pagina esterna scorrerà quando l'IFRAME è al passaggio del mouse, ma non otterrai alcun evento finché l'IFRAME non è fuori strada. – hallvors

4

Sembra come se fosse un bug in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1084121

Quindi non ci può essere un modo semplice per gestire questa situazione. Ma poiché l'azione ha un effetto anche se non viene inviata, c'è una soluzione che può essere utilizzata. Potrebbe non funzionare in ogni situazione, ma dovrebbe coprire molti casi.

Invece di rilevare wheel event, si rileva scroll e si utilizza un interruttore che rileva se si fa clic sul mouse. Se la finestra scorre e il mouse non viene cliccato, probabilmente è lo mousewheel. Altri casi saranno se lo si attiva da uno script, nel qual caso questo può essere gestito facilmente anche.

Un caso che non gestirai è quando la finestra non può più scorrere, quindi non otterrai l'evento.

Sarebbe simile a questa:

var mouseDown = false; 

function handle_wheel() { 
    if (!mouseDown) { 
     document.getElementById("debug-textarea").value = document.getElementById("debug-textarea").value + ' wheel'; 
    } else { 
     document.getElementById("debug-textarea").value = document.getElementById("debug-textarea").value + ' scroll'; 
    } 
} 

window.onscroll = handle_wheel; 
window.onmousedown = function() { 
    mouseDown = true; 
} 
window.onmouseup = function() { 
    mouseDown = false; 
} 

http://jsfiddle.net/wu9y6yua/4/

+0

bello, ma non mi aiuta - in primo luogo, non riesco a rilevare il delta della ruota – digitalzoomstudio

+0

in secondo luogo, lo scopo è una barra di scorrimento personalizzata, l'overflow del corpo è nascosto in modo che non scorre effettivamente (quindi nessun evento di scorrimento) - check nuovo esempio – digitalzoomstudio