Подтвердить что ты не робот

Почему не звучат аудио- и видео-события?

Мне было интересно, почему какой-то мой javascript не будет работать, пока я не подумаю, что звуковые события не пузыряют дерево DOM, например. timeupdate -event.

Есть ли обоснование для того, чтобы не пропускать события пузырька аудио- и видео-тегов?

4b9b3361

Ответ 1

Причина возникновения пузырьков событий заключается в решении двусмысленного вопроса о том, какой элемент является предполагаемой целью события. Итак, если вы нажмете на div, вы хотели бы нажать div или его родитель? Если у ребенка нет прикрепленного обработчика щелчка, он проверяет родителя и так далее. Я уверен, что вы знаете, как это работает.

Причина, по которой звуковые события не пузырятся, заключается в том, что они не имеют смысла ни для какого другого элемента. Там нет двусмысленности, когда вы вызываете timeupdate в аудиоэлементе, независимо от того, предназначено ли оно для самого аудиоэлемента или его родительского div, поэтому нет необходимости его пузыря.

Вы можете прочитать более полную историю пузырьков событий здесь

Деление событий

Событие делегирование по-прежнему возможно, используя этап захвата события. Просто добавьте true в качестве третьего аргумента для addEventListener, который выглядит следующим образом:

document.addEventListener('play', function(e){
    //e.target: audio/video element
}, true);

Обратите внимание, что это событие не пузырится, но спускается с DOM-дерева и не может быть остановлено с помощью stopPropagation.

Если вы хотите использовать это с помощью методов jQuery.on/.off(например, для расширения имен и других расширений событий jQuery). Следующая функция, принятая в форме webshim library, должна стать полезной:

$.createEventCapturing = (function () {
    var special = $.event.special;
    return function (names) {
        if (!document.addEventListener) {
            return;
        }
        if (typeof names == 'string') {
            names = [names];
        }
        $.each(names, function (i, name) {
            var handler = function (e) {
                e = $.event.fix(e);

                return $.event.dispatch.call(this, e);
            };
            special[name] = special[name] || {};
            if (special[name].setup || special[name].teardown) {
                return;
            }
            $.extend(special[name], {
                setup: function () {
                    this.addEventListener(name, handler, true);
                },
                teardown: function () {
                    this.removeEventListener(name, handler, true);
                }
            });
        });
    };
})();

Использование:

$.createEventCapturing(['play', 'pause']);

$(document).on('play', function(e){
    $('audio, video').not(e.target).each(function(){
        this.pause();
    });
});