全屏视频不允许在Firefox上滚动

时间:2015-03-30 10:45:40

标签: javascript css firefox scroll mousewheel

我正在使用fullscreen.js脚本,在我的一个屏幕中,我将有一个全屏Vimeo视频。显然这会导致FF出现问题,并且一旦我到达带有视频的屏幕,就会阻止我向上或向下滚动。该问题已提交到脚本的GitHub页面,但作者将其视为FF问题(https://github.com/alvarotrigo/fullPage.js/issues/803)。

我将所有这些与基础CSS一起用于响应式视频:

<div class="flex-video widescreen vimeo"> 
    <iframe src="<?php the_sub_field('video') ?>" 
        width="400" 
        height="225" 
        frameborder="0" 
        webkitAllowFullScreen 
        mozallowfullscreen 
        allowFullScreen></iframe> 
</div>

错误就是这个:https://bugzilla.mozilla.org/show_bug.cgi?id=779286但我不知道它是在Mac上的FF 36上解决的。铬也没有发生这个问题。

以下是GitHub线程中其他人的问题示例:http://jsbin.com/tunove/1/edit?html,output

1 个答案:

答案 0 :(得分:6)

问题:

您正在查看的Mozilla错误实际上是指the fullscreen mode API,这是一个已修复的无关API。我认为您正在寻找的错误报告就是这个:

Bug 1084121 - Mouse wheel event is captured by iframe and not propogated.

  

重现的步骤:

     

我有一个div,我在其中手动捕获鼠标滚轮事件,然后使用   滚动div。在这个div中,我有一个嵌入式youtube   视频,在iframe中。

     

实际结果:

     

滚动时,如果鼠标悬停在iframe上,则不再滚动   因为所有鼠标事件,包括鼠标滚轮事件,都可以   由iframe捕获,不会发送到父窗口。

     

预期结果:

     

鼠标滚轮事件应该已传播到父级   窗口。这是chrome和safari中的行为。

     

由于iframe位于不同的域中,因此似乎没有   任何可行的解决方法。

此错误报告仍处于打开状态,似乎未在实施过程中。

此外,根据错误报告,任何规范都没有定义此行为。

为了它的价值,我给这个错误报告投票以增加重要性。我同意,这是一个用户体验问题。

解决方法:

不幸的是,就直接修复wheel事件问题而言,GitHub问题中的建议是关于跨源iframe的所有内容。如果框架内容位于同一域或以其他方式控制,您可以在iframe中添加另一个事件侦听器,但Same-Origin Policy会阻止此跨域。

唯一可用于阻止iframe窃取跨域框架的wheel事件的选项包括:

  • 使用透明div覆盖大部分或全部iframe。
  • 在iframe上使用pointer-events: none;。这也会阻止点击视频,因此它与使用透明div覆盖整个视频具有相同的效果。

其他选项:

此问题显然仅限于wheel事件,因为可以在滚动iframe时滚动父文档。

<iframe src="data:text/html;charset=utf-8,%3Chtml%3E%3Cbody%3E%3Cp%3EScroll%20over%20this.%3C/p%3E%3C/body%3E%3C/html%3E" style="width: 100%; height: 100px;"></iframe>

<div style="background: red; width: 20px; height: 5000px;"></div>

fullPage.js不是这样构造的,但是如果iframe的父元素实际上是一个可滚动的元素,那么就可以监听scroll事件并对此作出反应。

这有点不稳定,但这是使用scroll事件而非wheel事件的类似示例。

示例(JSFiddle):

var autoScrolling = false;
$('.wrap').on('scroll', function(e) {
    if (autoScrolling) {
        return;
    }
    //Get this element and find the number of children.
    var $this = $(this);
    var children = $this.children('.pane').length;
    //Find the height of each pane, and the current position.
    var paneHeight = this.scrollHeight / children;
    var position = this.scrollTop / paneHeight;
    var positionRound = Math.round(position);
    //Find the target position.
    var positionOff = position - positionRound;
    var toShow = null;
    if (positionOff < 0) {
        toShow = positionRound - 1;
    }
    else if (positionOff > 0) {
        toShow = positionRound + 1;
    }
    //If scrolling to a new pane, find the next one.
    if (toShow !== null) {
        autoScrolling = true;
        $this.animate({
            scrollTop: paneHeight * toShow
        }, {
            duration: 1000,
            complete: function() {
                setTimeout(function() {
                    autoScrolling = false;
                }, 500);
            }
        });
    }
});
html,
body {
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
}
.wrap {
    height: 100%;
    width: 100%;
    overflow: auto;
}
.pane {
    width: 100%;
    height: 100%;
    position: relative;
}
iframe {
    background: white;
    border: 0;
    outline: 0;
    display: block;
    position: absolute;
    width: 80%;
    height: 80%;
    left: 10%;
    top: 10%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div class="wrap">
    <div class="pane" style="background: red;">
        <iframe src="data:text/html;charset=utf-8,%3Chtml%3E%3Cbody%3E%3Cp%3EScroll%20over%20this.%3C/p%3E%3C/body%3E%3C/html%3E"></iframe>
    </div>
    <div class="pane" style="background: green;">
        <iframe src="data:text/html;charset=utf-8,%3Chtml%3E%3Cbody%3E%3Cp%3EScroll%20over%20this.%3C/p%3E%3C/body%3E%3C/html%3E"></iframe>
    </div>
    <div class="pane" style="background: blue;">
        <iframe src="data:text/html;charset=utf-8,%3Chtml%3E%3Cbody%3E%3Cp%3EScroll%20over%20this.%3C/p%3E%3C/body%3E%3C/html%3E"></iframe>
    </div>
</div>