1

I wrote this code based off of Felix Kling's response to click toggle. I was wondering if there was a better way of writing it, and how to close an element when another is clicked.

I am using this to play certain points of the video on click and close them on a secondary click.

I have wrote a function to close on escape with classes, but it slows down and breaks the event from completing.

$(document).on('keydown', function(e) {
    if(e.keyCode == 27) {
        var buttons = $("button");
        if ( buttons.hasClass("open") ) {
            myVideo.currentTime = 2.8;
            myVideo.play();
            setTimeout(function() {
                myVideo.pause();
            }, 540);
            buttons.removeClass("open");
        }
    }
})


var myVideo = document.getElementById("video");

$("#button-1").clickToggle(function() {
    myVideo.currentTime = 2;
    myVideo.play();
    $(this).addClass("open");
    setTimeout(function() {
        myVideo.pause();
    }, 900);
}, function() {
    myVideo.currentTime = 2.8;
    myVideo.play();
    setTimeout(function() {
        myVideo.pause();
    }, 540);
});

$("#button-2").clickToggle(function() {
    myVideo.currentTime = 3.05;
    myVideo.play();
    setTimeout(function() {
        myVideo.pause();
    }, 850);
}, function() {
    myVideo.currentTime = 3.8;
    myVideo.play();
    setTimeout(function() {
        myVideo.pause();
    }, 680);
});
Community
  • 1
  • 1
alexmattorr
  • 362
  • 4
  • 15

1 Answers1

1

Well, for a more reliable way to pause the video at the correct spot, you could listen for the timeupdate event:

myVideo.addEventListener("timeupdate", function(){
    if(myVideo.currentTime >= 2.9) {
        myVideo.pause();
    }
});

Of course, you wouldn't want that listener to keep executing when you start to play the next segment. You could remove the listener, and replace it with a new one for the next segment. Or you could store your video start and stop times in an array like this:

var videoSegments = [
        { startTime: 2, endTime: 2.9},
        { startTime: 2.8, endTime: 3.34},
        { startTime: 3.05, endTime: 3.9},
        { startTime: 3.8, endTime: 4.48}
    ];

Now you can use just one listener:

myVideo.addEventListener("timeupdate",function(){
    if(myVideo.currentTime >= videoSegments[currentSegment].endTime) myVideo.pause();
});

And you don't need clickToggle either if your onclick function does something like this:

$(button).click( function() {

     ...other stuff here...

     currentSegment++;
     myVideo.currentTime = videoSegments[currentSegment].startTime;
     myVideo.play();
});

Each time you click, it advances the video to the next segment and plays it. The listener will stop the video when it reaches the right spot.

Here's a working example: http://jsfiddle.net/w30j2acc/2/

Seamus
  • 4,539
  • 2
  • 32
  • 42
  • How would you assign currentSegment? I see you are trying to iterate over the array with currentSegment++ but the console throws currentSegment undefined. – alexmattorr Apr 09 '15 at 23:11
  • Yeah. You have to initialize it. It might make sense to initialize it in the same place you initialize the array. It depends on what else you need to accomplish. For example, if you wanted more than one video element, you might want to use $.data() to keep track of the counter for each. – Seamus Apr 10 '15 at 00:53
  • @Alexsmander I've added a working example. Maybe that will be useful for you. – Seamus Apr 10 '15 at 02:28
  • thank you. That helped me understand it better. Using this method would you be able to bind a currentSegment to a particular click event? – alexmattorr Apr 10 '15 at 03:08
  • Sure. Like, if you wanted separate buttons for each segment? You could do something like this: http://jsfiddle.net/w30j2acc/3/ – Seamus Apr 10 '15 at 03:15