Search code examples
javascriptvideosettimeoutvideo-player

setTimout within event handler


I built an iFrame viewer for some videos here.

It works pretty well, except when someone clicks on the button for video A and then clicks video B's button while video A is still playing. The viewer will close when video A would have finished and cuts video B off.

I have read a lot of questions and answers about using setTimeout inside of other functions. I believe the problem is that setTimeout is taking the duration info from video A and not updating when video B is clicked, often referred to as a 'this' problem.

I have read a lot of questions and answers and tried a lot of solutions, but I can't make it work. This is my first javascript project, so I'd appreciate your help very much. Here is a simplified version of the code:

***
<body>
***
//The buttons contain data for the viewer, including the video's duration and the YouTube address.  This is a sample button:

<div id="MovieButtons" class="MovieButtons">
<button class="MovieButton" data-MovieId="Memorial" data-MovieDur="2740000"     data-MovieAdr="https://www.youtube.com/embed/sMVZbMxD-Xw?autoplay=1&amp;controls=0&amp;">Memorial Video</button>
        </div> <!--End Moviebuttons-->

<script language="JavaScript" type="text/javascript" src="jquery_3.1.0.min.js"></script>
<script>

$(document).ready(function(){

//initial state has the viewer hidden.  It appears when a movie is clicked.

$("#viewer").hide();

//declaring global variables -- the .val property will be assigned inside the function.

    var MovieId = {};
    var MovieDur = {};
    var MovieAdr = {};      

//When a movie is clicked, viewer gets its info from the button, 

    $(".MovieButton").on("click", function(){

    MovieId.val= $(this).attr("data-MovieId");
    MovieDur.val= Number($(this).attr("data-MovieDur"));
    MovieAdr.val= $(this).attr("data-MovieAdr");

//shows the viewer

    $("#viewer").show();

//viewer loads movie and plays

    $("#viewer").html("<iframe src="+oMovieAdr.val+" width=\"560\" height=\"315\" style=\"position:relative; left: 22%; top:0%; frameborder=\"1\" allowfullscreen></iframe>");

//Reset mechanism closes the viewport and hides the stop button, also restores normal page look.  This is where the problem is.

function reset(){
        $("#viewer").hide();
        $("#viewer").html("<iframe src= none></iframe>");
        };

//Automatically closes viewport when the movie ends.
    setTimeout(function(){
        reset();}, oMovieDur.val);

});     //end of $(".oMovieButton").on("click", function(){

}); //end of $(document).ready(function(){
</script>

Solution

  • For future reference,

    Amadan's suggestion to shut one timer and start another was a good one, but the new timer was still using the original video duration within the event timer. The solution I found was to use a jquery plugin by Ben Alman called doTimeout: http://benalman.com/projects/jquery-dotimeout-plugin/

    I rewrote the timeout lines, originally:

    setTimeout(function(){
        reset();}, oMovieDur.val);
    

    as follows ('loop' is just an id):

    $.doTimeout( 'loop', oMovieDur.val, function(){
    reset();
    });
    

    and now things work properly. Thanks to Amadan and Ben Alman