【问题标题】:How to prevent event bubbling when clicking on HTML5 video controls in Firefox在 Firefox 中单击 HTML5 视频控件时如何防止事件冒泡
【发布时间】:2014-09-14 23:43:57
【问题描述】:

在 Firefox 中,当视频标记包含在 a 标记中时,在单击视频暂停时使用标准视频控件也会重定向。我怎样才能让它像其他浏览器一样运行,例如点击暂停只会暂停视频,也不会重定向。这就是我需要的。

这是一个简单的演示:http://jsfiddle.net/me2loveit2/cSTGM/

<a href="http://www.google.com" target="_blank">
    <video controls="" muted="" preload="auto" id="testid" width="500">
        <source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"/>
        <source src="http://www.w3schools.com/html/mov_bbb.ogg" type="video/ogg"/>
        <source src="http://www.w3schools.com/html/mov_bbb.webm" type="video/webm"/>
        <img src="http://dummyimage.com/1044x585/000/fff"/>
    </video>
</a>

【问题讨论】:

    标签: javascript html firefox video html5-video


    【解决方案1】:

    你得到的标记是无效的,HTML5 spec 明确指出

    a 元素可以围绕整个段落、列表、表格等,甚至整个部分,只要其中没有交互内容(例如按钮或其他链接)。 em>

    视频导航实际上是包含按钮的交互式内容。

    由于某种原因,在 Chrome 中单击控件不会触发锚点,而在 Firefox 中会触发。
    这取决于浏览器如何使用 Shadow DOM 构造控件,并且由于标记是无效的并且对此没有真正的标准,这是任何人的猜测。

    你应该做的是删除锚点并在点击视频时使用javascript重定向,像这样

    $('#testid').on('click', function() {
        var win = window.open('http://www.google.com', '_blank');
        win.focus();
    });
    

    这会给你有效的标记,因为你可以删除包装锚,但它也不能解决单击控件时不重定向的问题,它完全相同,因为控件仍在视频中并且在 Firefox 中触发点击处理程序,但在 Chrome 中不触发。

    在 webkit 中,这些控件可能以某种方式被 -webkit-media-controls 伪类作为目标,但是 Firefox 似乎没有任何此类伪类,所以这也不起作用。

    您所剩下的是依赖于控件似乎始终位于底部的事实,并且它们大约 30 像素高,因此您可以将锚点覆盖在视频顶部并省略一点底部的一部分。
    这适用于所有浏览器,并且您将拥有有效的标记。

    <video controls="" muted="" autoplay preload="auto" id="testid" width="500">
        <!-- stuff -->
    </video>
    <a href="http://www.google.com" class="overlay" target="_blank"></a>
    

    为确保锚点放置正确并具有正确的大小,可以使用一点 javascript

    $('.overlay').each(function() {
        var vid = $(this).prev('video');
        $(this).css({
            position : 'fixed',
            top      : vid.offset().top + 'px',
            left     : vid.offset().left + 'px',
            width    : vid.width() + 'px',
            height   : (vid.height() - 30) + 'px',
        });
    });
    

    FIDDLE

    【讨论】:

    • 感谢 adeneo。如果我希望正确完成覆盖,似乎没有办法绕过覆盖......和自定义控件,因为它们在悬停在覆盖上时不会淡入。此外,有时控件可能具有圆形边缘,因此为了使其完美,我必须制作自定义控件并将它们放在顶部。
    • 是的,我认为这是要走的路,我也在考虑启动一些自定义控件并将悬停事件附加到叠加层,但认为答案有点过分,据我所知,覆盖基本上是答案,也是使其跨浏览器工作的唯一方法。谢谢采纳!
    【解决方案2】:

    考虑到视频事件(playpause 等)在之后触发

    ,除了使用自定义控件之外,我不确定是否有可能以真正优雅的方式绕过控件行为em> 点击事件。这是一个硬编码默认控件的近似高度的解决方案。我不喜欢硬编码,但在其他方面我认为还可以。它适用于所有avideo 元素,并且不会对元素进行任何过度迭代。 setTimeout 位是 event.preventDefault() 杀死链接行为和播放/暂停行为的解决方法。
    $(document).on('click', 'a', function(event) {
        var video = $('video:hover').first();
        if (video.length && video.offset().top + video.height() - event.pageY < 35) {
            var anchor = $(this);
            var href = anchor.attr('href');
            var target = anchor.attr('target');
            anchor.attr('href', 'javascript:;');
            anchor.attr('target', null);
            setTimeout(function() {
                anchor.attr('href', href);
                anchor.attr('target', target);
            }, 1);
        }
    });
    

    【讨论】:

      【解决方案3】:

      您可以通过为您的视频创建自定义控件并仅将video 标记与a 标记而不是控件包装来实现此目的。这使您可以选择跨浏览器对视频进行一致的外观控制,但您必须对 CSS 有很好的理解才能使其在浏览器中看起来良好且一致。我已经包含了您想要的 CodePen 项目,以及一些自定义控件。这些控件在浏览器中看起来不太好,但我认为您可以理解。

      http://codepen.io/anon/pen/dtHsb

      【讨论】:

        【解决方案4】:

        非常难看,但通常的解决方案不起作用,因为 event.stropPropagation() 仅适用于事件处理程序,而 event.preventDefault() 会破坏控件。

        http://jsfiddle.net/cSTGM/28/

        $('#testid').click(function() {
            link = $(this).parent();
            originalHref = link.attr('href');
            originalTarget = link.attr('target');
            link.attr('href', 'javascript:void(0)');
            link.attr('target', '_self');
            setTimeout(function() {
                link.attr('href', originalHref);
                link.attr('target', originalTarget);        
            }, 0);
        });
        

        【讨论】:

        • 很好的解决方法,但现在 a 标签完全没用了,我一开始就可以把它去掉。所以当我点击视频而不是控件时,我仍然需要它来重定向我。
        • 是的,抱歉,我无法在 Chrome 上进行测试,所以我无法理解要求。我会尝试自定义控件,因为它们似乎不允许使用默认值编写脚本。
        【解决方案5】:

        如果是VIDEO标签,我们只需要防止重定向

        $('#testid').click(function() {
            if (event.target.tagName !=== 'VIDEO') {
                //redirect
            }
        });
        

        【讨论】:

        • 请详细说明您的代码。仅代码答案很少有帮助。
        猜你喜欢
        • 2012-04-25
        • 2016-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-21
        • 2010-11-12
        • 1970-01-01
        相关资源
        最近更新 更多