Search code examples
javascripthtmljquery

Automatically play / pause video if they are in the viewport / not in the viewport


I need to play/pause videos if they are in the viewport/not in the viewport.

It works so far. The problem is, that if the user presses pause, then the video just starts playing again.

// Limitation: Does not work if the element is
// out of view because it is too far right or left
$.fn.isInViewport = function() {
    var elementTop = $(this).offset().top;
    var elementBottom = elementTop + $(this).outerHeight();

    var viewportTop = $(window).scrollTop();
    var viewportBottom = viewportTop + $(window).height();

    return elementBottom > viewportTop && elementTop < viewportBottom;
};

setInterval(function() {
    $('video').each(function(){
        if ($(this).isInViewport()) {
            $(this)[0].play();
        } else {
            $(this)[0].pause();
        }
    });
}, 1000);
#right {
  position: absolute;
  top: 2000px;
}
#video1 {
  position: absolute;
  left: 0px;
  top: 1000px;
}
#video2 {
  position: absolute;
  left: 0px;
  top: 2000px;
}

body {
  width: 500px;
  height: 3000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="info"></div>

<div id="down">
  scroll down please...
</div>

<video id="video1" controls muted>
  <source src="https://www.w3schools.com/html/movie.mp4" type="video/mp4">
  <source src="https://www.w3schools.com/html/movie.ogg" type="video/ogg">
  Your browser does not support the video tag.
</video>

<video id="video2" controls muted>
  <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"/>
  <source src="https://www.w3schools.com/html/mov_bbb.ogg" type="video/ogg"/>
  Your browser does not support the video tag.
</video>

I tried to observer the Play/Pause button so I can hook into the event, but the video tag is a shadow dom and I dont know how to deal with it.

https://jsfiddle.net/6agbqjsL/


Solution

  • I figured it out. This way the video only starts playing again if it gets out of the viewport and into the viewport again:

    // Limitation: Does not work if the element is
    // out of view because it is too far right or left
    $.fn.isInViewport = function() {
        var elementTop = $(this).offset().top;
        var elementBottom = elementTop + $(this).outerHeight();
    
        var viewportTop = $(window).scrollTop();
        var viewportBottom = viewportTop + $(window).height();
    
        return elementBottom > viewportTop && elementTop < viewportBottom;
    };
    
    setInterval(function() {
        $('video').each(function(){
    
            let id = $(this).attr("id");
            let played = $(this).attr("played");
    
            if ($(this).isInViewport()) {
                if (played == "false") { 
                    $(this)[0].play();
                    $(this).attr("played", "true");  
                }
            } else {
                if (played == "true") { 
                    $(this)[0].pause();
                    $(this).attr("played", "false");  
                }
            }
        });
    }, 1000);
    #right {
      position: absolute;
      top: 2000px;
    }
    #video1 {
      position: absolute;
      left: 0px;
      top: 1000px;
    }
    #video2 {
      position: absolute;
      left: 0px;
      top: 2000px;
    }
    
    body {
      width: 500px;
      height: 3000px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <div id="info"></div>
    
    <div id="down">
      scroll down please...
    </div>
    
    <video id="video1" controls muted played="false">
      <source src="https://www.w3schools.com/html/movie.mp4" type="video/mp4">
      <source src="https://www.w3schools.com/html/movie.ogg" type="video/ogg">
      Your browser does not support the video tag.
    </video>
    
    <video id="video2" controls muted played="false">
      <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"/>
      <source src="https://www.w3schools.com/html/mov_bbb.ogg" type="video/ogg"/>
      Your browser does not support the video tag.
    </video>

    This way the video does never play again automatically after it was paused:

    // Limitation: Does not work if the element is
    // out of view because it is too far right or left
    $.fn.isInViewport = function() {
        var elementTop = $(this).offset().top;
        var elementBottom = elementTop + $(this).outerHeight();
    
        var viewportTop = $(window).scrollTop();
        var viewportBottom = viewportTop + $(window).height();
    
        return elementBottom > viewportTop && elementTop < viewportBottom;
    };
    
    setInterval(function() {
        $('video').each(function(){
    
            var id = $(this).attr("id");
            let played = $(this).attr("played");
    
            if ($(this).isInViewport()) {
                if (played == "false") { 
                    $(this)[0].play();
                    $(this).attr("played", "true");
                }
            } else {
                $(this)[0].pause();
            }
        });
    }, 1000);
    #right {
      position: absolute;
      top: 2000px;
    }
    #video1 {
      position: absolute;
      left: 0px;
      top: 1000px;
    }
    #video2 {
      position: absolute;
      left: 0px;
      top: 2000px;
    }
    
    body {
      width: 500px;
      height: 3000px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <div id="info"></div>
    
    <div id="down">
      scroll down please...
    </div>
    
    <video id="video1" controls muted played="false">
      <source src="https://www.w3schools.com/html/movie.mp4" type="video/mp4">
      <source src="https://www.w3schools.com/html/movie.ogg" type="video/ogg">
      Your browser does not support the video tag.
    </video>
    
    <video id="video2" controls muted played="false">
      <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"/>
      <source src="https://www.w3schools.com/html/mov_bbb.ogg" type="video/ogg"/>
      Your browser does not support the video tag.
    </video>