Легкий способ обнаружения поддержки для события перехода без фреймворков, таких как jQuery или Modernizr?

Кто-нибудь там нашел простой способ определить, поддерживает ли браузер событие перехода или нет в vanillaJs, особенно таким образом, который действительно работает во всех основных браузерах?: (

Я нашел эту неотвеченную тему здесь: Тест для поддержки событий перехода в Firefox и довольно много практически работающих хаков.

В настоящий момент я добавляю сборщиков событий во все префиксы поставщиков, и это работает (хотя я считаю, что это отвратительный подход, который причиняет мне боль каждый раз, когда я смотрю на него). Но IE8 и IE9 вообще не поддерживают его, поэтому мне нужно обнаружить эти два и рассматривать их отдельно.

Я бы предпочел сделать это без взлома браузера и, безусловно, без огромных библиотек/фреймворков, таких как jQuery

Я сделал фрагмент jsfiddler, который иллюстрирует мою проблему. Появляется кнопка, которая вызывает диалог. Когда диалог удаляется щелчком по закрытию, он переходит в верхнюю и непрозрачную, а после завершения перехода предполагается, что он отображается = none. Но если переход никогда не запускается (как в IE8 и IE9), диалог никогда не удаляется, заставляя его закрывать кнопку диалога show, уничтожая UX. Если бы я мог обнаружить, когда переход не работает, я мог бы просто установить display = none при закрытии для этих браузеров.

http://jsfiddle.net/QJwzF/22/

window.listenersSet = false;
window.dialogShouldBeVisible = false;

window.showMyDialog = function () {
    var myDialog = document.getElementById('dialog'),
        myClose = document.getElementById('close');
    if (!listenersSet) {
        if (!window.addEventListener) { // IE8 has no addEventListener
            myclose.attachEvent('onclick', function () {
                hideMyDialog();
            });
        } else {
            myClose.addEventListener('click', function () {
                hideMyDialog()
            });

            ['webkitTransitionEnd','oTransitionEnd', 'otransitionend', 'transitionend'].forEach(function (eventName) {
                myDialog.addEventListener(eventName, function (e) {
                    if (e.target === myDialog && e.propertyName === 'top') { // only do trigger if it is the top transition of the modalDialog that has ended
                        if (!dialogShouldBeVisible) {
                            myDialog.style.display = 'none';
                            e.stopPropagation();
                        }
                    }
                });
            });
        }
        listenersSet = true;
    }

    myDialog.style.display = 'block';
    myDialog.style.top = '15px';
    myDialog.style.opacity = '1';
    dialogShouldBeVisible = true;
}

window.hideMyDialog = function () {
    var myDialog = document.getElementById('dialog'),
        myClose = document.getElementById('close');
    myDialog.style.top = '-5%';
    myDialog.style.opacity = '0.1';
    dialogShouldBeVisible = false;
}

Он работает в Opera, Firefox, Chrome и IE10, но не в IE8 и IE9 (afaik)

Если бы я плохо описал мою проблему, сообщите мне, и я постараюсь сделать лучшую работу!:)

Ответ 1

Я бы определенно использовал этот небольшой script, доступный в Github. Он перечислил страницу Modernizr "Кросс-браузерные полисы" , поэтому ему можно доверять, но самому Modernizr не требуется.

Примеры на странице Github script написаны с использованием jQuery (и я не могу понять почему), но jQuery также не требуется, поскольку он написан в vanilla js.

Таким образом, у вас будет полезный метод whichTransitionEnd. Я не могу проверить его прямо сейчас на моем ноутбуке без IE8/IE9, но я предполагаю, что этот метод вернет false (или что-то ложное) в этих браузерах.

var transition = transitionEnd(box).whichTransitionEnd(); 
// return for example "webkitTransitionEnd"

Тогда будет довольно легко настроить таргетинг на те браузеры, где переходы (и, следовательно, события transitionend) не поддерживаются. Надеюсь, что это будет толчок в правильном направлении.

ИЗМЕНИТЬ

После настройки с приведенным выше кодом OP придумал гораздо более короткую версию оригинала script. Он сохраняет большое количество байтов и только обнаруживает поддержку этого события, и в случае его поддержки возвращает имя самого события.

Вы можете найти здесь в качестве сущности и прочитать об этом в комментариях к этому ответу.

Ответ 2

Скопированный из bootstrap-перехода, он не только возвращает true, если браузер поддерживает переход, но также возвращает правильное имя события

  function transitionEnd() {
    var el = document.createElement('div')//what the hack is bootstrap

    var transEndEventNames = {
      WebkitTransition : 'webkitTransitionEnd',
      MozTransition    : 'transitionend',
      OTransition      : 'oTransitionEnd otransitionend',
      transition       : 'transitionend'
    }

    for (var name in transEndEventNames) {
      if (el.style[name] !== undefined) {
        return transEndEventNames[name];
      }
    }

    return false // explicit for ie8 (  ._.)
  }

Надеюсь, это поможет.

Eidt: Я немного изменил функцию загрузки по умолчанию, поэтому он не возвращает объект, а строку.