如何在没有浏览器嗅探的情况下支持transitionend?

时间:2013-05-08 11:11:51

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

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

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

如果($ .browser.msie&& $ .browser.version< = 9),我们理解这是不好的做法。

这是一个快速举例说明我的观点:

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');
});

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

在旧浏览器中使此活动有效的最佳方法是什么?

感谢您的帮助。

2 个答案:

答案 0 :(得分:5)

您可以检查浏览器中是否支持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');
    }
});

答案 1 :(得分:3)

您可以查看jQuery Transit的源代码。这是非常好的书面和自我解释。

原则很简单:

  1. 获取转换属性的名称,以嗅探浏览器的呈现引擎;
  2. 接下来,我们有一个包含不同浏览器中所有事件名称的列表,您可以从中获取该特定浏览器的事件名称
  3. 在任何其他情况下,如果不存在transitionend属性,则应考虑实施setTimeout计时器,以实现最佳的跨浏览器效率。
  4. 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事件将会触发