在没有jQuery或Modernizr等框架的情况下,轻松检测对transitionend事件的支持?

时间:2013-10-28 13:23:47

标签: javascript browser-feature-detection transitionend

有没有人找到一种简单的方法来检测浏览器是否支持transitionilland事件在vanillaJs中,特别是在所有主流浏览器中实际运行的方式? :(

我在这里找到了这个没有答案的帖子:Test for transitionend event support in Firefox,以及相当多的工作黑客。

现在我正在将eventlisteners批量添加到所有供应商前缀中,并且它有点成功(尽管我认为这是一种可怕的方法,每次看到它都会伤害我的眼睛)。但是IE8和IE9根本不支持它,所以我需要检测这两个,并单独处理它们。

我更愿意在没有浏览器嗅探的情况下做到这一点,并且绝对没有像jQuery那样的大型库/框架

我制作了一个jsfiddler片段来说明我的问题。有一个按钮可以生成一个对话框。通过单击关闭删除对话框时,它将在顶部和不透明度中转换,在结束转换后,它应该显示为= none。但是如果转换端永远不会被触发(例如在IE8和IE9中),则永远不会删除对话框,使其覆盖显示对话框按钮,从而破坏UX。如果我能检测到transitionend何时不起作用,我可以在关闭这些浏览器时设置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)

如果我的工作做得不好解释我的问题,请告诉我,我会尽力做得更好! :)

2 个答案:

答案 0 :(得分:12)

从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: 我修改了一点默认的bootstrap函数,所以它不返回对象而是字符串。

答案 1 :(得分:8)

我肯定会在Github上使用this small script。 它列在Modernizr "Cross-browser polyfills" page中,因此可以信任,但Modernizr本身不需要

脚本的Github页面中的示例是使用jQuery编写的(我无法理解为什么)但jQuery也不需要,因为它是用 vanilla js

就像这样,您将拥有一个有用的whichTransitionEnd方法。我现在无法在没有IE8 / IE9的笔记本电脑上进行测试,但我想这种方法会在这些浏览器中返回false(或任何虚假的)。

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

然后很容易定位那些不支持转换(以及transitionend事件)的浏览器。希望这将是朝着正确方向的推动。

修改

使用上面的代码调整后,OP提出了原始脚本的更短版本。它节省了大量字节,只检测对此事件的支持,如果支持,则返回事件本身的名称。

你可以找到here作为要点,并在对这个答案的评论中阅读更多相关内容。