15

有没有人找到一种简单的方法来检测浏览器是否支持 vanillaJs 中的 transitionend 事件,尤其是在所有主要浏览器中都可以使用的方式?:(

我在这里找到了这个未回答的线程:Test for transitionend event support in Firefox,以及很多几乎可以工作的黑客。

现在,我正在向所有供应商前缀批量添加事件侦听器,并且效果不错(尽管我认为这是一种可怕的方法,每次看到它都会伤害我的眼睛)。但是IE8和IE9根本不支持,所以我需要检测这两个,分别对待。

我宁愿在没有浏览器嗅探的情况下执行此操作,并且绝对没有像 jQuery 这样的大型库/框架

我制作了一个 jsfiddler 片段来说明我的问题。有一个生成对话框的按钮。当通过单击关闭删除对话框时,它会以顶部和不透明度进行转换,并且在结束转换后它应该显示=无。但是如果从不触发transitionend(如在IE8和IE9中),则永远不会删除对话框,使其覆盖显示对话框按钮,破坏用户体验。如果我可以检测到 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)

如果我在解释我的问题时做得不好,请告诉我,我会努力做得更好!:)

4

2 回答 2

12

从引导转换复制,如果浏览器支持转换,它不仅返回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:我修改了一些默认的引导函数,所以它不返回对象,而是返回字符串。

于 2014-09-19T15:12:37.257 回答
8

我肯定会使用Github 上的这个小脚本。它列在 Modernizr “跨浏览器 polyfills”页面中,因此可以信任,但 Modernizr 本身不是必需的。

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

就像这样,您将有一个有用的whichTransitionEnd方法可用。如果没有可用的 IE8/IE9,我现在无法在我的笔记本电脑上测试它,但我猜这个方法会false在那些浏览器中返回(或任何错误的)。

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

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

编辑

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

你可以在这里找到它作为一个要点,并在这个答案的评论中阅读更多关于它的信息。

于 2013-10-29T01:52:06.753 回答