使用jQuery跳过CSS转换

时间:2012-03-27 14:25:28

标签: jquery css-transitions

我想在某些条件下跳过CSS转换。我不想在样式表中添加特殊的无过渡样式,或者在JavaScript中复制样式表的样式。到目前为止,我发现的最佳解决方案是

if (condition) {
  $el.css({'-webkit-transition-duration': '0s'});
  setTimeout(function() {
    $el.css({'-webkit-transition-duration': ''});
  }, 0);
};
$el.addClass('transitionClass');

(为了简洁起见,我省略了非WebKit CSS。请在http://jsfiddle.net/TrevorBurnham/zZBhx/查看它。)

我不喜欢这个,因为

  1. 这是详细的,
  2. 它引入了潜在的竞争条件,例如:如果队列中有另一个超时,将在$el上添加或删除一个类。
  3. 有更好的方法吗?

4 个答案:

答案 0 :(得分:3)

这是跳过元素CSS转换的可靠方法,代码来自Mozilla的X-Tag Web Components library

var prefix = (function () {
  var styles = window.getComputedStyle(document.documentElement, ''),
      pre = (Array.prototype.slice
        .call(styles)
        .join('')
        .match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o'])
      )[1];
  return {
    dom: pre == 'ms' ? pre.toUpperCase() : pre,
    lowercase: pre,
    css: '-' + pre + '-',
    js: pre[0].toUpperCase() + pre.substr(1)
  };

})();

var requestFrame = (function(){
  var raf = window.requestAnimationFrame ||
    window[prefix.lowercase + 'RequestAnimationFrame'] ||
    function(fn){ return window.setTimeout(fn, 20); };
  return function(fn){
    return raf.call(window, fn);
  };
})();

var skipTransition = function(element, fn, bind){
  var prop = prefix.js + 'TransitionProperty';
  element.style[prop] = element.style.transitionProperty = 'none';
  var callback;
  if (fn) callback = fn.call(bind);
  requestFrame(function(){
    requestFrame(function(){
      element.style[prop] = element.style.transitionProperty = '';
      if (callback) requestFrame(callback);
    });
  });
};

如何使用 - 此代码段假设您已在foo元素的宽度上设置了转换,并希望在没有元素转换的情况下立即将其更改为100px。

var foo = document.querySelector('#foo')
skipTransition(foo, function(){
    foo.style.width = '100px';
});

实时示例

单击示例中的每个彩色div - 红色div在skipTransition函数中设置其宽度样式,从而阻止转换并立即设置样式。蓝色div的宽度设置正常,没有skipTransition,CSS过渡效果正常:http://codepen.io/csuwldcat/pen/nFlse

答案 1 :(得分:3)

我知道你说你不想在CSS中复制整个对象的样式,但是你有没有想过为转换添加一个特殊的类?然后你可以在HTML中定义这样的元素:

<div id='#yourobject' class='transition'>

当你不想要转换时,只需这样做(假设是jQuery):

$('#yourobject').removeClass('transition');
.... do some manipulation here
$('#yourobject').addClass('transition');

答案 2 :(得分:2)

这是一种方法:克隆元素,将类添加到克隆中,并用克隆替换原始元素。巴姆!没有过渡。

示范:http://jsfiddle.net/TrevorBurnham/yXhBz/

但这并不理想,因为这会破坏对应用程序中可能包含的原始元素的任何存储引用。所以我欢迎在现有元素上同步运行的答案。

答案 3 :(得分:0)

以下是我写的几个jquery插件:

$.fn.redraw = function(){
    var redraw = $(this).first()[0].offsetHeight || $('body')[0].offsetHeight; // forces a draw in the main window if the element is off screen
    return this;
};

$.fn.cssNoTransition = function(){
    $(this)
            .css('transition', 'none')
            .css.apply(this,arguments)
            .redraw()
            .css('transition', '');
    return this;
};

假设css说要转换高度,请使用它:

this.$el.cssNoTransition({height: 0}).css({height: 200});