Я заметил такие похожие вопросы, как "как мне перехватить события касания?" или "события мышиного мозга?"точки зрения
во множественном числе : обработчики запускаются много раз, даже когда мы ожидаем, что будет запущено одно событие
Глубина : события все глубже кипят в дереве, прежде чем наш обработчик их поймает.
Примеры:
a touchstart
может сопровождаться mousedown
и наоборот в устройстве, которое имеет как мышь, так исенсорный экран,
a touchend
может сопровождаться mouseup
по аналогичным причинам,
a animationstart
банкаможет сопровождаться многими другими подобными событиями в зависимости от того, как вы написали CSS,
a animationend
также может сопровождаться многими подобными событиями по вышеуказанным причинам.
Если нам нужно запустить наш обработчик один раз за набор похожих событий, то есть событий, которые генерируются одним действием, например, человеком, который нажимает sth.нам нужно ввести блокировку события и использовать 2 обработчика, один в начале события и один обработчик в конце , даже если нам не нужен или нужен обработчик побочного события .
Блокировка может быть свойством родительского узла выше в дереве, как вы уже догадались.
Для печально известной пары событий: animationstart
- animationend
такая функция может быть:
var oneTransition = (function(){
var $parent,
type,
callback,
unlockCallback,
newCallback,
start = 'webkitTransitionStart otransitionstart oTransitionStart msTransitionStart transitionstart',
end = 'webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend';
unlockCallback = function(){
$parent.data('oneTransitionLock', false);
};
newCallback = function(e){
if($parent.data('oneTransitionLock'))
return;
else
$parent.data('oneTransitionLock', true);
callback(e);
};
return function(){
var args = Array.prototype.slice.call(arguments, 0);
$parent = $(args[0]); // 1st arg
type = args[1]; // 2nd arg
callback = args[2]; // 3rd arg
if((args.length < 3) || ((type != 'start') && (type != 'end')) || (typeof(callback) != 'function'))
return;
$parent.off(start).off(end);
if(type == 'start'){
$parent.data('oneTransitionLock', false);
$parent.on(start, newCallback);
$parent.on(end, unlockCallback);
}else if(type == 'end'){
$parent.on(start, unlockCallback);
$parent.on(end, newCallback);
}
}
})();
, и вы можете назвать ее следующим образом:
oneTransition(node, 'start' or 'end', funcion(){...});
Интересно то, что она может выполняться либо для начала, либо для конца анимации:
1-й аргу.ссылка на узел,
2-й аргумент.строка, представляющая событие для нашего обратного вызова и
3-е arg.наш реальный обратный вызов.
jsFiddle