HTML5 and Javascript to play videos only when visible

℡╲_俬逩灬. 提交于 2019-11-27 18:37:26

Using the isInViewport plugin and jQuery, here's my code for the task

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

OK, I think, it must be something like this:

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

function checkScroll() {

    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);
Pierre Olivier Tran

None of the above seemed to work for me, but I finally found a way: you'll need the visible plugin, and this little piece of code right here:

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

This will allow any video to play only when it gets into viewport. By replacing visible( true ) by visible() , you can set it to play only when the entire video DOM element is in viewport.

Need to check if the video is visible during the scrolling.

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

Old question, but just wanted to add my two cents, I initially started with the jQuery code above, but ran into some issues with the implementation. This solution should work with multiple videos, and also prevents a problem where the user pauses a video and tries to scroll away and it just starts again:

<script>
    var videoList = [];
    var scrollPauseList = [];
    var clickedPauseList = [];
</script>
<script>    
    var myScrollFunc = function() {

        $(".video-js").each(function(){ 

            var inView = $(this).is(":in-viewport");
            var isPaused = $(this)[0].player.paused();
            var playerIdx = videoList.indexOf(this.id);
            var scrollPaused = scrollPauseList[playerIdx];
            var clickPaused = clickedPauseList[playerIdx];

            if (inView) {                       
                var hasEnded = $(this)[0].player.ended();
                var curTime = $(this)[0].player.currentTime();
                var hasStarted = curTime > 0;
                if(hasStarted && !hasEnded && !clickPaused)
                {
                    scrollPauseList[playerIdx] = false;
                    $(this)[0].player.play();
                }
            } else if(!isPaused) {                      
                scrollPauseList[playerIdx] = true;
                $(this)[0].player.pause();
            }
        });
    };      

    $(window).scroll(myScrollFunc);     
</script>   

<video  
  class="video-js" controls></video>

<script>
$(".video-js").each(function(){ 
        videoList[videoList.length] = this.id;
        scrollPauseList[scrollPauseList.length] = false;
        clickedPauseList[scrollPauseList.length] = false;
    }); 

for(var i = 0; i < videoList.length; i++)
{
    var playerID = videoList[i];
    var player = videojs(playerID);

    player.on('pause', function() {
        var pID = videoList.indexOf(this.id());

        if(!scrollPauseList[pID])
        {
            clickedPauseList[pID] = true;
            scrollPauseList[pID] = false;
        }
        else
        {
            clickedPauseList[pID] = false;
            scrollPauseList[pID] = false;
        }
    });
}       
</script>

I've scrubbed some stuff, and i'm using video-js, so you may need to modify it a bit to get your implementation to work.

Me on the web

Tried many solutions, the only one partially working is the one posted below. The problem is that having 3 videos on the page, the second one and the third one are basically controlled by the first one.

So they start playing when the page is loaded (while they are supposed to play when in viewport) and they get paused when the first get paused, any suggestion on having this working with multiple videos?

Tried using getElementById but didn't work, tried also jquery plugins but no good results.

Here you have the www page where you can see what happen and all source code of course.

http://185.197.128.183/~monompro/

window.onload = function() {

    var videos = document.getElementsByTagName("video"),
        fraction = 0.8;

    function checkScroll() {

        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);
}

Using jQuery, isInViewport, and Coffeescript, the complete solution for me looked like this:

$(window).scroll ->
  $('video:in-viewport').each -> $(@)[0].play()
  $('video:not(:in-viewport)').each -> $(@)[0].pause()
Leandro Videla

This is how I managed to play a video only when the user scrolls to it. I used IsInViewport plugin. Hope you find it useful!

$(window).scroll(function() {

    var video = $('.yourvideo');

    $(video).each(function(){

        if(video.is(':in-viewport')){

            video[0].play();

            video.removeClass('yourvideo');
            //I removed class to stop repeating the action ".play()" when it is scrolled again.
        }
    });
});

In case anyone else runs into this question, I was unable to use Saike's solution on my WordPress site because of the way the videos were auto embedded (MediaElement player). However, qwazix's solution worked with some modification. Here is the jQuery code that works with the IsInView plugin. Here are my include scripts (placed at the end of footer.php in my theme folder).

<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="js/isInViewport.min.js" type="text/javascript"></script>
<script src="js/scrollview.min.js" type="text/javascript"></script>

And the jQuery code (modify 400 to your tolerance liking)

  $(function() {
      $(window).scroll(function() {
          $('.wp-video-shortcode').each(function() {
              var str = $(this).attr('id');
              var arr = str.split('_');
              typecheck = arr[0];
              if ($(this).is(":in-viewport( 400 )") && typecheck == "mep") {
                  mejs.players[$(this).attr('id')].media.play();
              } else if (typecheck == "mep") {
                  mejs.players[$(this).attr('id')].media.pause();
              }
          });
      });
  });

Only issue I have with this code is that it does restart a video clip on scroll even if paused by the user. Wasn't a deal-breaking issue on my site. Here is the code in action: Ultrasoundoftheweek.com

$('video').each(function(){
    if ($(this).is(":in-viewport")) {
        $(this)[0].play();
    } else {
        $(this)[0].pause();
    }
})
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!