2014-02-08 3 views
6

У меня есть прослушиватель видео-событий html5, который должен ждать до нужного времени, а затем приостанавливать видео, пока пользователь принимает участие в викторине. Первый «урок» отлично работает, а второе видео также добавляет слушателя с правильным временем паузы. Но при воспроизведении второго видео он всегда останавливается на 170 секунд, время паузы от видео FIRST.video 'timeupdate' прослушиватель забывает значения

Кроме того, когда я проверяю панель разработчика 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); 
}; 

первого $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); 
     } 
    }); 
}; 
}) 

ответ

2

Каждый раз, когда вы вызываете свою функцию pause, вы создаете новый экземпляр функции timeListener. Любая ссылка на timeListener является ссылкой на тот, который вы только что создали. Поэтому, когда вы удаляете прослушиватель событий, вы удаляете новую функцию, а не ту, которую вы ранее прикрепляли.

В Javascript в данной функции не имеет значения, где вы объявляете переменные и функции; они всегда «поднимаются» на вершину. Поэтому, даже если вы написали timeListener функцию после, ваш звонок removeEventListener, ваш код ведет себя так, как если бы вы заявили его в верхней части pause. Вот почему обычно рекомендуется объявлять все ваши переменные и функции перед запуском любого другого кода (и JSLint вам будет тяжело, если вы этого не сделаете). Исключением является то, что вы явно назначаете функцию переменной.

Вы можете это исправить, объявив timeListenerвне из 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); 
}; 
+0

Извините, возможно, я должен был объяснить. Функция паузы должна быть вызвана только один раз, каждый раз, когда видео загружается, чтобы присоединить прослушиватель событий. Я бы назвал его 'setPause()' и фактически изменил его на это сейчас. – Tules

+0

Непонятно, что вы пытаетесь сделать. Возможно, вы хотели бы обновить пример кода в вопросе. – brianchirls

+0

Я сделаю это, когда вернусь с работы – Tules

Смежные вопросы