Vimeo iFrame Stealing Mouse Wheel Event on Firefox

This is basically by design. Your code should be completely unaware of what the user does inside an IFRAME (especially one from a different origin like YouTube - this is a part of the web's security architecture, as mandated by the Same Origin Policy.)

Now, even in the cross-origin case browsers can choose to let scrolling affect the frame's ancestor if the frame itself doesn't scroll. This scrolling should happen without any events firing on the top document - see Chrome's behaviour if you scroll to the bottom of this IFRAME and keep scrolling: 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
});

What you'll see is that when you have scrolled to the end of the IFRAME, the main document will scroll but no events will fire until the mouse is above the parent document.


It looks like it's a bug in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1084121

So there may not be a straightforward way to handle this. But since the action has an effect even if it's not being dispatched, there's a workaround that can be used. It may not work in every situation, but it should cover many cases.

Instead of detecting wheel event, you detect scroll, and use a switch detecting if the mouse is clicked or not. If the window scrolls and the mouse isn't clicked, then it's most likely from the mousewheel. Other cases will be if you trigger it from a script, in which case this can be handled easily also.

One case you won't handle is when the window cannot scroll anymore, then you won't get the event.

It would look like this:

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/