视频'timeupdate'监听器会忘记值

Tul*_*les 6 javascript javascript-events html5-video angularjs

我有一个html5视频事件监听器,应该等到正确的时间,然后在用户参加测验时暂停视频.第一个"课程"工作正常,第二个视频也可以为听众添加正确的暂停时间.但是在播放第二个视频时,它始终会在170秒处暂停,即第一个视频的暂停时间.

此外,当我检查Chrome的开发面板时,它实际显示timeCache为在播放视频后立即恢复为之前的视频值; 除非视频已通过 170标记,否则它将使用230秒的timeCache值.起初我以为这是因为旧的事件监听器仍然附着,但我已经消除了这种可能性,问题仍然存在.这是链接http://koreanwordgame.com/grammar/

var setPause = function (time) {
   var video = $("video").get(0);
   var timeCache = time;
   video.removeEventListener('timeupdate', timeListener, false);
   function timeListener (){
    if (video.currentTime >= timeCache && video.currentTime < (timeCache + 0.3)) {
        video.pause();
    }}
   video.addEventListener('timeupdate', timeListener);
};
Run Code Online (Sandbox Code Playgroud)

$watch每次加载新课程时,都会触发指令中的第一个,它会绑定ended事件以及timeupdate侦听器setPause(),然后加载并播放视频.这个想法是setPause设置视频到达时自动暂停的时间,然后第二个$watch等待直到所有问题都被回答,然后再播放视频的其余部分(通常是祝贺消息)

app.directive('videoWatcher', function () {
return function (scope, video, attrs) {
    scope.$watch(attrs.videoLoader, function () {
        $(video[0]).bind('ended', function () {
            $(this).unbind('ended');
            if (!this.ended) {
                return;
            }
            scope.tutorialNumber++;
            scope.$apply();
            scope.loadFromMenu();
        });
        setPause(scope.currentTutorial.pause);
        video[0].load();
        video[0].play();
    });
    scope.$watch(attrs.congrats, function(){
        var cT = scope.currentTutorial;
        if (scope.questionNumber === cT.material.length){
            video[0].play();
            setTimeout(function () {
                video[0].play();
            }, 500);
        }
    });
};
})
Run Code Online (Sandbox Code Playgroud)

bri*_*rls 2

每次调用pause函数时,都会创建该timeListener函数的一个新实例。对的任何引用timeListener都是对您刚刚创建的引用。因此,当您删除事件侦听器时,您将删除新函数,而不是之前附加的函数。

在 Javascript 中,在给定的函数中,在哪里声明变量和函数并不重要;重要的是。他们总是被“提升”到顶部。因此,即使您在调用timeListener编写该函数,您的代码的行为也就像您在 的顶部声明它一样。这就是为什么在运行任何其他代码之前声明所有变量和函数通常是一个好主意(如果不这样做,JSLint 会给您带来困难)。例外情况是当您将函数显式分配给变量时。removeEventListenerpause

您可以通过在oftimeListener 之外pause声明来解决此问题,因此它将始终是对前一个实例的引用。像这样:

var timeListener;
function pause(time) {
    //timeCache is unnecessary
    var video = $("video").get(0),
        end = time + 0.3; //cache this so you don't have to add every time

    if (timeListener) {
        //remove previous timeListener function, if there is one
        video.removeEventListener('timeupdate', timeListener, false);
    }

    //make a new function and save it for later as timeListener
    timeListener = function () {
        if (video.currentTime >= time && video.currentTime < end) {
            video.pause();
        }
    };
    video.addEventListener('timeupdate', timeListener);
};
Run Code Online (Sandbox Code Playgroud)