2013-08-07 4 views
2

Я использую отличное решение (найдено here) для использования функции обратного вызова a la jQuery при использовании переходов CSS.Включение префиксов поставщиков в переходах CSS делает обратные вызовы дважды

Проблема заключается в том, что если я использую префиксы, Chrome по крайней мере связывает два события: один для webkitTransitionEnd, а второй для transitionend и, конечно же, срабатывает обратный вызов дважды. Вот мой фрагмент кода:

jQuery("#main").one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) { 
    console.log("POUM!"); 
}); 

Я что-то не так?

ответ

6

Вы не ошибетесь. Chrome использует как префиксные, так и не префиксные версии.

Есть несколько вариантов:

  1. Использование внешней переменной.

    var fired = false; 
    jQuery("#main").one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) { 
        if (! fired) { 
         fired = true; 
         console.log("POUM!"); 
        } 
    }); 
    
  2. Использование своего рода обнаружения, чтобы получить одну переменную для transitionend (ниже использует Modernizr, и взят из их documentation):

    var transitionend = (function(transition) { 
        var transEndEventNames = { 
         'WebkitTransition' : 'webkitTransitionEnd',// Saf 6, Android Browser 
         'MozTransition' : 'transitionend',  // only for FF < 15 
         'transition'  : 'transitionend'  // IE10, Opera, Chrome, FF 15+, Saf 7+ 
        }; 
    
        return transEndEventNames[transition]; 
    })(Modernizr.prefixed('transition')); 
    
    // then 
    jQuery("#main").one(transitionend, function(e) { 
        console.log("POUM!"); 
    }); 
    

ПРИМЕЧАНИЕ:

Safari 6, похоже, вызывает onload для всего, что установлено в CSS. Таким образом, если у вас есть (предполагая, что все префиксы)

#main { 
    width: 40px; 
    height: 40px; 
    transition: all 200ms; 
} 

Safari запустит transitionend с width и height на нагрузке.Есть несколько способов, чтобы обойти эту проблему:

  • Использование более конкретного перехода-свойства (но если вы установили, что в CSS, он все равно будет вызывать)
  • Выполните следующие действия в JavaScript (это не красивая вещь, но она должна позаботиться о том, края корпуса и он по-прежнему работает в Chrome) fiddle

    var transitionProperty = 'background-color', 
        startColor = jQuery("#main").on(transitionend, function(e) { 
         var el = $(this); 
         if (transitionProperty === e.originalEvent.propertyName && el.css(transitionProperty) !== startColor) { 
          console.log("POUM!"); 
          // This is to make it only happen once. 
          $(this).off(transitionend); 
         } 
        }).css(transitionProperty); 
    
+0

Хорошо, хотя эта «проблема» все еще заставляет меня хотеть похищать и убивать некоторых детей -webkit, это решение замечательно. Я даже узнал, что у Modernizr есть префиксный метод! Большое спасибо, мужик! –

+0

@kalley Спасибо за скрипт! Я начал использовать его, и он отлично поработал, пока я не заметил, что он больше не срабатывает, как это должно быть в Safari. Идеи? – INT

+2

@INT Похоже, Safari выполнил то, что сделал Chrome, и удалил префикс из свойства, но изменил имя события на 'transitionend' (без camelcase). Я обновляю скрипт на основе документации [Modernizr] (http://modernizr.com/docs/#prefixed) – kalley

1

Не уверен, если это решает ваши проблемы, но по этой ссылке: http://ianlunn.co.uk/articles/opera-12-otransitionend-bugs-and-workarounds/

Это цитата говорит:

Да, шесть! В Opera 11 событие transitionEnd дважды запускалось для каждого одного окончания перехода. В Opera 12 событие transitionEnd будет запускать шесть раз, будь то привязка через JavaScript или jQuery.

Это для Opera, но я предполагаю, что эта же проблема относится и к вам. Затем следует сказать, что вы можете устранить эту проблему, выполнив следующие действия:

$(document).bind("otransitionend", function(){ 
    $(this).unbind("otransitionend"); 
    alert("Transition Ended"); 
}); 
+0

Похоже, он работает, но ... мой бог ... В Опере еще хуже, потому что это вызывает otransitionend, oTransitionEnd и transitionend. Спасибо в любом случае! –

2

у меня была такая же проблема, с Chrome дважды стреляли, один раз для «transitionend» и снова " webkitTransitionEnd ». С вдохновением от решения Remyabel я оказался с чем-то довольно простым.

jQuery("#main").one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) { 
$(this).off("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend"); 
    console.log("POUM!"); 
}); 

 Смежные вопросы

  • Нет связанных вопросов^_^