how can I pause a youtube embed when a user scrolls away

13,723

You done a great job with HTML5 player and the function checkScroll().
It seem you have trouble to use it with the YouTube JS Player, well if you take the time to read the doc, you discover that the YouTube player is just an iframe.

Try this live example i made : http://jsbin.com/cocatuta/15/edit?js,output

So basically i just replace :

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

By this :

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

And add two function playVideo and pauseVideo.

function playVideo() {
  player.playVideo();
}

function pauseVideo() {
  player.pauseVideo();
}

Full code :

//play when video is visible
var videos = document.getElementsByTagName("iframe"), fraction = 0.8;

function checkScroll() {


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

    var x = 0,
        y = 0,
        w = video.width,
        h = video.height,
        r, //right
        b, //bottom 
        visibleX, visibleY, visible,
        parent;


    parent = video;
    while (parent && parent !== document.body) {
      x += parent.offsetLeft;
      y += parent.offsetTop;
      parent = parent.offsetParent;
    }

    r = x + parseInt(w);
    b = y + parseInt(h);


    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) {
      playVideo();
    } else {
      pauseVideo()

    }
  }

};

window.addEventListener('scroll', checkScroll, false);
window.addEventListener('resize', checkScroll, false);

//check at least once so you don't have to wait for scrolling for the video to start
window.addEventListener('load', checkScroll, false);
checkScroll();

Hope it's help ! And yes, read the doc "is even supposed to help you" (eventually)

Share:
13,723
new_frontenddev
Author by

new_frontenddev

Hi I am a graphic designer slowly transitioning to front end web development. I am curious to learn how to make my designs dynamic with the use of codes and new to javascript so constantly use stackoverflow to help me with my issues.

Updated on June 11, 2022

Comments

  • new_frontenddev
    new_frontenddev almost 2 years

    I have been trying to look for help with respect getting a video to pause when a user scrolls away. I have already been able to find help for html5 videos but now I also need to know how the youtube API can be used for the same.

    the html structure I have that embeds the YouTube is as follows

         <div class="ytube-container">
    
         <iframe id="vplayer" 
          src="//www.youtube.com/embed/qKaMgJwBItM?modestbranding=1&showinfo=0&modestbranding=0&controls=1&rel=0&autoplay=1&vq=hd720" 
        frameborder="0"webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
    
        </div>
    

    I used the following for html5 - does the youtube API have a very different method to do the same?

        <script>
        //play when video is visible
        var videos = document.getElementsByTagName("video"), fraction = 0.8;
    
        function checkScroll() {
    
        for(var i = 0; i < videos.length; i++) {
        var video = videos[i];
        var x = 0,
        y = 0,
        w = video.offsetWidth,
        h = video.offsetHeight,
        r, //right
        b, //bottom
        visibleX, visibleY, visible,
        parent;
    
        parent = video;
        while (parent && parent !== document.body) {
        x += parent.offsetLeft;
        y += parent.offsetTop;
        parent = parent.offsetParent;
        }
    
        r = x + w;
        b = y + h;
    
        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);
    
        //check at least once so you don't have to wait for scrolling for the video to start
        window.addEventListener('load', checkScroll, false);
        checkScroll();
    
        </script>  
    

    I am not sure I understand how to entirely use the Youtube API I was able to find a code that stops one player if the other is playing but I dont see how that can be manipulated to achieve what I need.

    <script>
    
    players = new Array();
    
    function onYouTubeIframeAPIReady() {
    var temp = $("iframe.vplayer");
    for (var i = 0; i < temp.length; i++) {
        var t = new YT.Player($(temp[i]).attr('id'), {
            events: {
                'onStateChange': onPlayerStateChange
            }
        });
        players.push(t);
    }
    
    }
    onYouTubeIframeAPIReady();
    
    
    function onPlayerStateChange(event) {
    
    if (event.data == YT.PlayerState.PLAYING) {
        var temp = event.target.a.src;
        var tempPlayers = $("iframe.yt_players");
        for (var i = 0; i < players.length; i++) {
            if (players[i].a.src != temp) players[i].stopVideo();
    
        }
    }
    }
    

  • new_frontenddev
    new_frontenddev almost 10 years
    makes more sense now! One question though. In your JSBin you used Javascript to call the player. The html is empty. But I want the html structure to stay for SEO. How would your code change if it stayed a tag "IFrame embeds using <iframe> tags"
  • new_frontenddev
    new_frontenddev almost 10 years
    When I used your full code from here it doesnt work on the iframe tag, but your Jsbin is using JS to make the player appear
  • new_frontenddev
    new_frontenddev almost 10 years
    I think it functions alright but it gives errors. Which is probably why it doesnt auto play when scrolled into view again Uncaught TypeError: Cannot read property 'playVideo' of undefined Uncaught TypeError: undefined is not a function
  • Firefog
    Firefog over 8 years
    @mpgn This was a amazing answer. is there any way to work this method with visibility of the iframe. So for example I i use this in a tab the video play automatically. I mean If the frame visible play the video else pause.
  • ilCosmico
    ilCosmico over 7 years
    Great!... any chance to make it works with more than one players?