Как использовать переход в jQuery?

Мне нужно определить, завершен ли переход CSS, прежде чем позволить функции повториться снова, чтобы не испортить поля.

Так как же у меня есть что-то вроде

if (transitionend == true) {
  // do stuff
} else {
  // do nothing
}

person JacobTheDev    schedule 20.08.2011    source источник


Ответы (5)


Приведенный ниже код будет срабатывать по событию перехода для любого элемента (элементов), который у вас есть в переменной $element. Существует четыре разных названия событий, поскольку я считаю, что они охватывают все несоответствия между браузерами. Замените комментарий «// ваш обработчик событий» любым кодом, который вы хотите запустить при запуске события.

$element.on('transitionend webkitTransitionEnd oTransitionEnd', function () {
    // your event handler
});
person xram    schedule 12.11.2012
comment
не могли бы вы добавить объяснение в поддержку вашего ответа, пожалуйста - person Max MacLeod; 12.11.2012
comment
вы также должны добавить некоторые пояснения - person il_guru; 12.11.2012
comment
Извините, я здесь новенький. Я добавил объяснение. - person xram; 13.11.2012
comment
Это лучший ответ в этой теме, потому что первоначальный человек просил jQuery. Я опечален тем, что люди жалуются на добавление объяснения, сам код говорит сам за себя (при условии, что вы изначально просто вставили код) - person Allison A; 23.01.2013
comment
+1 очень рад найти это - даже не подозревал, что эти события существуют - person kinakuta; 02.04.2013
comment
otransitionend повторяется. Один из них должен быть mstransitionend для поддержки IE. - person Alejandro Pérez; 30.07.2013
comment
@aperezroca Исправил ответ :) - person Terry; 02.01.2014
comment
Используйте $element.one вместо $element.on, чтобы предотвратить многократное выполнение. - person mrReiha; 29.08.2015
comment
Единственное событие, которое вам нужно прослушать сейчас, это стандартное 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);
person Amin Eshaq    schedule 20.08.2011
comment
Спасибо, но я видел этот документ раньше и не мог понять ни головы, ни хвоста. Я новичок в javascript, поэтому добавление прослушивателей событий и всего этого для меня ничего не значит. Я нашел способ сделать это самостоятельно, но я добавил ваш ответ за усилия :) Также опубликовал свой ответ. - person JacobTheDev; 21.08.2011

Используйте данные jQuery, чтобы прикрепить к элементу данные с отслеживанием состояния. Используйте логическое значение, чтобы «заблокировать» события, и переверните логическую переменную после завершения перехода. Используйте код xram для одновременного подключения всех событий перехода между браузерами.

Итак, на вашем примере...

  1. onclick установить this.data («переход», правда)
  2. когда срабатывает переход, установите this.data('transitioning', false)
  3. не выполнять анимацию, если this.data('transitioning') == true. это фиксируется и проверяется в вашем событии клика.
person Allison A    schedule 23.01.2013
comment
Это действительно полезно, потому что код xram может выполняться несколько раз. - person Hengjie; 29.03.2014
comment
@Hengjie Я так не думаю, браузеры поддерживают либо версию без префикса, либо версию с префиксом ... никогда обе. - person Salman von Abbas; 03.01.2015
comment
Только что протестировано в Google Chrome и сразу же получил переход, за которым следует webkitTransitionEnd. Я не мог понять, почему мой конечный код перехода срабатывал дважды, пока не установил предупреждение для event.type и не увидел, что он срабатывает для обоих событий. - person primehalo; 24.04.2015

Вы можете создать метод, который будет помнить, когда конец перехода был вызван в последний раз, и, таким образом, вызовет обратный вызов только один раз.

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');
});
person Pouya    schedule 29.09.2015
comment
Разве вы не должны отменить подписку на событие, используя off? - person Stephen Lautier; 29.09.2015
comment
Если вы хотите, чтобы это вызывалось только один раз, вам нужно, как вы предлагаете, использовать off, но в этом случае вы можете использовать jQuery.one, который делает то же самое. Здесь идея заключалась в том, чтобы объединить все переходы для всех свойств в один обратный вызов, может быть, тогда следует изменить имя метода? - person Pouya; 01.10.2015
comment
Это не правильно! Что значит работает один раз? запускается один раз между кучей узлов, которые производят одно и то же событие после анимации, или запускается один раз за время жизни элемента? В любом случае этот код не работает... - person centurian; 05.11.2018

Я заметил такие похожие вопросы, как "как мне перехватывать события touchend?" или "события mouseup?" и т. д.

Они все похожи для этих точек зрения

  1. множественное число: обработчики запускаются много раз, даже если мы ожидаем, что они будут запущены одним событием.

  2. глубина: события всплывают глубже в дереве, прежде чем наш обработчик их поймает.

Примеры:

  1. за touchstart может следовать mousedown и наоборот на устройстве с мышью и сенсорным экраном,

  2. за touchend может следовать mouseup по тем же причинам,

  3. за animationstart может следовать множество других подобных событий в зависимости от того, как вы написали css,

  4. за 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. 1-й аргумент. ссылка на узел,

  2. 2-й аргумент. строка, представляющая событие для нашего обратного вызова и

  3. 3-й аргумент. наш фактический обратный вызов.

jsFiddle

person centurian    schedule 05.11.2018