【问题标题】:How to support transitionend without browser sniffing?如何在没有浏览器嗅探的情况下支持transitionend?
【发布时间】:2013-05-02 14:15:29
【问题描述】:

我有一些 javascript 会触发一些样式更改,这些更改会导致 CSS 转换。

我应该如何挂钩在转换完成后将执行的回调。显然在旧浏览器中它会立即转换,但这些也不会识别 transitionend 事件。

如果 ($.browser.msie && $.browser.version

这里有一个简单的例子来说明我的观点:

HTML

<div>test</div>

CSS

div {
    border: 1px solid black;
    transition: width 2s;
    width: 5px
}

.test {
    width: 100px;
}

JS

$(function(){
    $(document).on('transitionend', function(){
        alert('transition complete');
    });
    $('div').addClass('test');
});

现场JS小提琴:http://jsfiddle.net/vsDrH/1/

让这个事件在旧浏览器中运行的最佳方法是什么?

感谢您的帮助。

【问题讨论】:

    标签: javascript jquery css cross-browser css-transitions


    【解决方案1】:

    您可以像这样检查浏览器是否支持 CSS 属性:

    http://jsfiddle.net/vsDrH/3/

    function isSupported(property) {
        return property in document.body.style;
    }
    
    $(function(){
        $(document).on('transitionend', function(){
            alert('transition complete');
        });
        $('div').addClass('test');
    
        if(!isSupported('transition')) {
            $(document).trigger('transitionend');
        }
    });
    

    【讨论】:

    • 这行不通! transitionend 是一个事件,不是 style 对象的属性,所以即使浏览器支持该事件,isSupported 函数也会返回 false。
    【解决方案2】:

    你可以看看jQuery Transit的源码。写得很好,一目了然。

    原理很简单:

    1. 您获取过渡属性的名称,以嗅探浏览器的渲染引擎;
    2. 接下来,我们有一个包含跨不同浏览器的所有事件名称的列表,您可以从中获取该特定浏览器的事件名称
    3. 在任何其他情况下,如果不存在 transitionend 属性,则应考虑实现 setTimeout 计时器,以获得最佳的跨浏览器效率。

    Javascript(直接来自:jQuery Transit Source Code

    // Helper function to get the proper vendor property name.
    // (`transition` => `WebkitTransition`)
    
    // (1)
    
    function getVendorPropertyName(prop) {
        // Handle unprefixed versions (FF16+, for example)
        if (prop in div.style) return prop;
    
        var prefixes = ['Moz', 'Webkit', 'O', 'ms'];
        var prop_ = prop.charAt(0).toUpperCase() + prop.substr(1);
    
        if (prop in div.style) { return prop; }
    
        for (var i=0; i<prefixes.length; ++i) {
           var vendorProp = prefixes[i] + prop_;
           if (vendorProp in div.style) { return vendorProp; }
        }
    }
    
    // (2)
    
    var eventNames = {
      'transition':       'transitionEnd',
      'MozTransition':    'transitionend',
      'OTransition':      'oTransitionEnd',
      'WebkitTransition': 'webkitTransitionEnd',
      'msTransition':     'MSTransitionEnd'
    };
    
    var eventName = eventNames[getVendorPropertyName('transition')] || null
    
    // (3)
    
    if ( eventName ) {
        // Use the 'transitionend' event if it's available.
        bound = true;
        element.bind(eventName, cb);
    } else {
        // Fallback to timers if the 'transitionend' event isn't supported.
        window.setTimeout(cb, delay);
    }
    

    这样做您将 100% 确定您的 transitionEnd 事件会触发

    【讨论】:

    • 'transition': 'transitionend',(否则在 Chrome 中不起作用)
    猜你喜欢
    • 2023-04-08
    • 2011-09-02
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 2011-10-15
    相关资源
    最近更新 更多