Обработчик кликов в конфликтах <video> с поведением Firefox

Я добавил видео на свой сайт с помощью проигрывателя HTML5 по умолчанию. Код выглядит так:

<video width="100%" height="100%" controls>
  <source src="http://media.sublimevideo.net/v/midnight-sun-short-edit-360p.mp4" type="video/mp4">
</video>

Я хотел сделать так, чтобы клик на видео останавливался или запускал видео. Поэтому я добавил следующее:

onclick="this.paused?this.play():this.pause();"

И все хорошо. Пока Firefox 35 не добавит эту функцию в плеер. Итак, теперь вы можете воспроизводить только видео, щелкнув правой кнопкой мыши и выбрав игру - обычный щелчок сначала сделает воспроизведение видео по собственному поведению, а затем немедленно приостановит его с помощью моего обработчика кликов. Грозный. Поэтому я придумал функцию JavaScript примерно так:

function startstop() {
  if ( FirefoxVersionNumber > 34 ) {
    // do nothing
  } else {
    // start or stop video
  }
}

Бит, на котором я застрял, - это проверить версию браузера? Все, что я попробовал, вернули, что номер версии Firefox был 5... что, я думаю, происходит из части Netscape.

Ответ 1

Вам нужно предотвратить поведение по умолчанию события click, так же, как вы предотвратили бы поведение по умолчанию для формы, если вы обрабатывали ее самостоятельно с помощью JavaScript.

Event.preventDefault является инструментом для задания.

Просто сделай

video.addEventListener('click', function (event) {
    event.preventDefault(); // Prevent the default behaviour in Firefox

    // Then toggle the video ourselves
    if (this.paused) {
        this.play();
    }
    else {
        this.pause();
    }
});

Вот скрипт, который работает как в Chrome (который не имеет встроенного поведения клика для переключения на видео), так и в Firefox (что, по крайней мере, в последних версиях): http://jsfiddle.net/LjLgkk71/

Как правило, вы должны забыть об обнюхивании браузеров, пока вы не поистине и полностью не исчерпали все другие возможности (за исключением использования его для работы с определенными известными причудами и ошибками в старых браузерах, относящихся к поведению, которое с тех пор был установлен или стандартизирован). Идея, которую вы выразили в вопросе, просто не применяя ваш обработчик кликов в определенных версиях браузера, была ошибочной; у вас нет способа узнать (и не я), что другие браузеры разделяют или будут в один прекрасный день делиться поведением Firefox. Если бы вы взяли свой подход, почти неизбежно, что он вернется, чтобы укусить вас, когда один из главных браузеров следовал примеру Firefox или когда один из ваших пользователей попытался использовать ваш сайт на Nintendo DS или что-то в этом роде.

Ответ 2

Вероятно, могут быть лучшие способы справиться с этим, но вот тот, который я придумал: я просмотрел примечания к выпуску для Firefox 35, и похоже, что одно из изменений, внесенных в 35, было исправление ошибки где метод .hasAttributes(), который, согласно спецификации, должен быть расположен на Element, ранее находился на Node. Итак, хотя это выглядит странно, вы можете сделать что-то вроде:

if(typeof InstallTrigger !== 'undefined' && 
   typeof Element.prototype.hasAttributes !== 'undefined') {
    // is Firefox >= 35
} 

Это основано на том, что typeof InstallTrigger !== 'undefined' будет идентифицировать Firefox в соответствии с этим ответом, и мы знаем, что .hasAttributes перемещен в Элемент, начиная с версии 35. Это предпочтительнее разбора пользовательского агента, потому что, в отличие от строки User Agent, он вряд ли будет подделан каким-либо образом.

В комментариях упоминалось, что кажется странным сделать вид обнаружения браузера, проверяя наличие несвязанного объекта JavaScript, но это практика, которая была установлена ​​и использовалась исторически для обнаружения версий определенного браузера выше определенной версии: Здесь статья, которая описывает часто используемые переменные, которые могут использоваться для обнаружения версий Internet Explorer >= заданный номер.