Мне нужно определить, завершен ли переход CSS, прежде чем позволить функции повториться снова, чтобы не испортить поля.
Так как же у меня есть что-то вроде
if (transitionend == true) {
// do stuff
} else {
// do nothing
}
Мне нужно определить, завершен ли переход CSS, прежде чем позволить функции повториться снова, чтобы не испортить поля.
Так как же у меня есть что-то вроде
if (transitionend == true) {
// do stuff
} else {
// do nothing
}
Приведенный ниже код будет срабатывать по событию перехода для любого элемента (элементов), который у вас есть в переменной $element. Существует четыре разных названия событий, поскольку я считаю, что они охватывают все несоответствия между браузерами. Замените комментарий «// ваш обработчик событий» любым кодом, который вы хотите запустить при запуске события.
$element.on('transitionend webkitTransitionEnd oTransitionEnd', function () {
// your event handler
});
$element.one
вместо $element.on
, чтобы предотвратить многократное выполнение.
- person mrReiha; 29.08.2015
transitionend
: оно поддерживается в Chrome 36+, WebKit 7.0.6+ и Opera 12.10+. У IE по-прежнему много проблем, но вам не нужен префикс ms-.
- person iono; 16.11.2016
Я думаю, что эта ссылка может быть вам полезна.
Существует одно событие, которое запускается при завершении переходов. В Firefox это событие — transitionend, в Opera — OTransitionEnd, а в WebKit — webkitTransitionEnd.
el.addEventListener("transitionend", updateTransition, true);
Используйте данные jQuery, чтобы прикрепить к элементу данные с отслеживанием состояния. Используйте логическое значение, чтобы «заблокировать» события, и переверните логическую переменную после завершения перехода. Используйте код xram для одновременного подключения всех событий перехода между браузерами.
Итак, на вашем примере...
Вы можете создать метод, который будет помнить, когда конец перехода был вызван в последний раз, и, таким образом, вызовет обратный вызов только один раз.
function transitionEndsOnce($dom, callback) {
var tick = Date.now();
$dom.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function(e) {
var diff = Date.now() - tick;
tick = Date.now();
if (diff > 20) { // this number can be changed, but normally all the event trigger are done in the same time
return callback && callback(e);
}
});
}
а затем просто используйте его таким образом
transitionEndsOnce($('...'), function(e){
console.log('transition ends once');
});
off
?
- person Stephen Lautier; 29.09.2015
Я заметил такие похожие вопросы, как "как мне перехватывать события touchend?" или "события mouseup?" и т. д.
Они все похожи для этих точек зрения
множественное число: обработчики запускаются много раз, даже если мы ожидаем, что они будут запущены одним событием.
глубина: события всплывают глубже в дереве, прежде чем наш обработчик их поймает.
Примеры:
за touchstart
может следовать mousedown
и наоборот на устройстве с мышью и сенсорным экраном,
за touchend
может следовать mouseup
по тем же причинам,
за animationstart
может следовать множество других подобных событий в зависимости от того, как вы написали css,
за 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-й аргумент. наш фактический обратный вызов.