HTML5 和 Javascript 仅在可见时播放视频

IT技术 javascript html video html5-video
2021-03-15 15:19:18

我有兴趣设置一个包含多个视频剪辑的 HTML 页面,以便每个视频剪辑仅在可见时播放,然后在看不见时暂停。

我发现了这个很好的例子,说明如何使用一个剪辑来实现这一点,但我一直无法修改代码以使用多个剪辑。也许我需要将此代码转换为易于重用的函数?

这是我到目前为止所拥有的(上面链接的 JS Bin 修改为 2 个剪辑而不是一个)。

此代码似乎仅适用于两个剪辑之一。

<!DOCTYPE html>
<html>
    <!--   Created using jsbin.com   Source can be edited via http://jsbin.com/ocupor/1/edit
    -->
    <head>
        <meta charset=utf-8 />
        <title>JS Bin</title>
        <style>
            #right {
                position: absolute;
                top: 2000px;
            }
            #video1 {
                position: absolute;
                left: 2000px;
                top: 2000px;
            }
            #video2 {
                position: absolute;
                left: 2000px;
                top: 3000px;
            }

        </style>

        <style id="jsbin-css">
        </style>
    </head>
    #
    <body style="width: 4000px; height: 4000px;">
        <div id="info"></div>
        <div id="down">
            scroll down please...
        </div>
        <div id="right">
            scroll right please...
        </div>
        <video id="video1">
            <source src="http://video-js.zencoder.com/oceans-clip.mp4"/>

        </video>
        <script>
            var video = document.getElementById('video1'), fraction = 0.8;

            function checkScroll() {
                var x = video.offsetLeft, y = video.offsetTop, w = video.offsetWidth, h = video.offsetHeight, r = x + w, //right
                b = y + h, //bottom
                visibleX, visibleY, visible;

                visibleX = Math.max(0, Math.min(w, window.pageXOffset + window.innerWidth - x, r - window.pageXOffset));
                visibleY = Math.max(0, Math.min(h, window.pageYOffset + window.innerHeight - y, b - window.pageYOffset));

                visible = visibleX * visibleY / (w * h);

                if (visible > fraction) {
                    video.play();
                } else {
                    video.pause();
                }
            }

            checkScroll();
            window.addEventListener('scroll', checkScroll, false);
            window.addEventListener('resize', checkScroll, false);
        </script>

        <video id="video2">
            <source src="http://video-js.zencoder.com/oceans-clip.mp4"/>

        </video>
        <script>
            var video = document.getElementById('video2'), fraction = 0.8;

            function checkScroll() {
                var x = video.offsetLeft, y = video.offsetTop, w = video.offsetWidth, h = video.offsetHeight, r = x + w, //right
                b = y + h, //bottom
                visibleX, visibleY, visible;

                visibleX = Math.max(0, Math.min(w, window.pageXOffset + window.innerWidth - x, r - window.pageXOffset));
                visibleY = Math.max(0, Math.min(h, window.pageYOffset + window.innerHeight - y, b - window.pageYOffset));

                visible = visibleX * visibleY / (w * h);

                if (visible > fraction) {
                    video.play();
                } else {
                    video.pause();
                }
            } checkScroll();
            window.addEventListener('scroll', checkScroll, false);
            window.addEventListener('resize', checkScroll, false);

        </script>

    </body>
</html>
6个回答

使用isInViewport插件和jQuery,这是我的任务代码

$('video').each(function(){
    if ($(this).is(":in-viewport")) {
        $(this)[0].play();
    } else {
        $(this)[0].pause();
    }
})
我正在尝试让这段代码为我工作,它要简单得多。不过我遇到了麻烦。由于我已切换到基于 wordpress 的站点,因此我的视频遵循以下示例格式:class="wp-video-shortcode" id="video-1115-1"
2021-04-21 15:19:18
任何修改 [0] 以使用此video-XXXX-X格式的方法?
2021-04-21 15:19:18
@KalleH.Väravas 在 2014 年发布此答案时并非如此,而且,这些深奥的规则只会阻止贡献。
2021-05-04 15:19:18
因为 OP 没有指定 jQuery 标签,所以被否决了。可以预料,问题是针对 vanilla javascript 的。
2021-05-07 15:19:18
我们可以向 Vimeo 申请声明它在 iframe 下运行吗?如何?
2021-05-12 15:19:18

好吧,我想,它一定是这样的:

var videos = document.getElementsByTagName("video");

function checkScroll() {
    var fraction = 0.8; // Play when 80% of the player is visible.

    for(var i = 0; i < videos.length; i++) {

        var video = videos[i];

        var x = video.offsetLeft, y = video.offsetTop, w = video.offsetWidth, h = video.offsetHeight, r = x + w, //right
            b = y + h, //bottom
            visibleX, visibleY, visible;

            visibleX = Math.max(0, Math.min(w, window.pageXOffset + window.innerWidth - x, r - window.pageXOffset));
            visibleY = Math.max(0, Math.min(h, window.pageYOffset + window.innerHeight - y, b - window.pageYOffset));

            visible = visibleX * visibleY / (w * h);

            if (visible > fraction) {
                video.play();
            } else {
                video.pause();
            }

    }

}

window.addEventListener('scroll', checkScroll, false);
window.addEventListener('resize', checkScroll, false);
这对我不起作用,但作为参考很有用。
2021-05-04 15:19:18
是的,分数只需要在某处定义-尽管答案很好:)
2021-05-06 15:19:18
我收到了一个“未定义分数”的 ReferenceError,但是一旦我重新添加了定义:分数 = 0.8;
2021-05-14 15:19:18

以上都不似乎为我工作,但我终于找到了一个办法:你需要visible插件,这一小段代码就在这里:

$(window).scroll(function() {
    $('video').each(function() {
        if ($(this).visible(true)) {
            $(this)[0].play();
        } else {
            $(this)[0].pause();
        }
    })
});

这将允许任何视频仅在进入视口时播放。通过替换visible( true )by visible() ,您可以将其设置为仅在整个视频 DOM 元素都在视口中时播放。

也谢谢你!正是我需要的滚动页面具有多个全屏视频部分,这些部分在 Chrome 和 Mac Safari 中没有表现。使用这个插件和上面的代码修复了一切。再次感谢!
2021-04-22 15:19:18
谢谢这个!
2021-05-01 15:19:18
您的解决方案效果最好!谢谢
2021-05-04 15:19:18
如果你们不想使用插件,请查看答案。
2021-05-05 15:19:18

需要检查视频在滚动过程中是否可见。

 $(window).scroll(function() {
    $('video').each(function(){
        if ($(this).is(":in-viewport")) {
            $(this)[0].play();
        } else {
            $(this)[0].pause();
        }
    })
});

你们都需要与时俱进并使用 IntersectionObserver(以及适当的 polyfill 或 babeifyl)。当页面滚动进/出视图时,此脚本将播放/暂停页面上的所有视频。繁荣。

<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver%2CIntersectionObserverEntry"></script> 
<script>
    let video = document.querySelector('video');
    let isPaused = false;
    let observer = new IntersectionObserver((entries, observer) => { 
        entries.forEach(entry => {
        if(entry.intersectionRatio!=1  && !video.paused){
            video.pause();
            isPaused = true;
        }
        else if(isPaused) {
            video.play(); 
            isPaused=false}
        });
    }, {threshold: 1});
    observer.observe(video);
</script>

来源

是的,可以很简单 if (entry.intersectionRatio !== 1) video.pause() else video.play()
2021-04-29 15:19:18
css-tricks.com/... - 回头看,是为了知道视频是否被自动暂停,
2021-05-07 15:19:18
看起来它应该被剥离。
2021-05-17 15:19:18
有点好奇isPaused国旗在做什么。它是某种性能标志,还是效果起作用所必需的?
2021-05-21 15:19:18