Как мне использовать transitionend в jQuery? - PullRequest
32 голосов
/ 21 августа 2011

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

Итак, как камера у меня что-то вроде

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

Ответы [ 5 ]

81 голосов
/ 12 ноября 2012

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

$element.on('transitionend webkitTransitionEnd oTransitionEnd', function () {
    // your event handler
});
6 голосов
/ 21 августа 2011

Я думаю, эта ссылка может быть вам полезна.

Существует одно событие, которое запускается при завершении переходов. В Firefox, это событие transitionend, в Opera, OTransitionEnd и в WebKit это webkitTransitionEnd.

el.addEventListener("transitionend", updateTransition, true);
2 голосов
/ 23 января 2013

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

Итак, для вашего примера ...

  1. onclick set this.data ('transitioning', true)
  2. при срабатывании transitionend установите this.data ('transitioning', false)
  3. не выполнять анимацию, если this.data ('transitioning') == true.это фиксируется и проверяется в вашем событии клика.
1 голос
/ 05 ноября 2018

Я заметил такие похожие вопросы, как "как мне перехватить события касания?" или "события мышиного мозга?"точки зрения

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

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

Примеры:

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

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

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

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

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

  3. 3-е arg.наш реальный обратный вызов.

jsFiddle

1 голос
/ 29 сентября 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');
});
...