简答
使用这个 CSS:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
加上这个 JS(没有 jQuery)......
someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions
或者这个带有 jQuery 的 JS ......
$someElement.addClass('notransition'); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
$someElement.removeClass('notransition'); // Re-enable transitions
...或使用您正在使用的任何其他库或框架的等效代码。
解释
这实际上是一个相当微妙的问题。
首先,您可能想要创建一个“notransition”类,您可以将其应用于元素以将其*-transition
CSS 属性设置为none
. 例如:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
(除了小问题 - 请注意那里缺少一个-ms-transition
。你不需要它。第一个完全支持转换的 Internet Explorer 版本是IE 10,它支持无前缀。)
但这只是风格,而且很容易。当你来尝试使用这个类时,你会遇到一个陷阱。陷阱是这样的代码不会像你天真期望的那样工作:
// Don't do things this way! It doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
someElement.classList.remove('notransition')
天真地,您可能认为高度的变化不会被动画化,因为它发生在应用 'notransition' 类时。但实际上,它将是动画的,至少在我尝试过的所有现代浏览器中是这样。问题是浏览器正在缓存它需要进行的样式更改,直到 JavaScript 完成执行,然后在一次重排中进行所有更改。因此,它会进行回流,无论是否启用过渡都没有净变化,但高度有净变化。因此,它会为高度变化设置动画。
您可能认为解决此问题的一种合理且干净的方法是将删除“notransition”类包装在 1ms 超时中,如下所示:
// Don't do things this way! It STILL doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
setTimeout(function () {someElement.classList.remove('notransition')}, 1);
但这也不能可靠地工作。我无法在 WebKit 浏览器中破坏上述代码,但在 Firefox(在慢速和快速机器上)上,您有时(似乎是随机的)会得到与使用幼稚方法相同的行为。我想这样做的原因是 JavaScript 执行速度可能足够慢,以至于超时函数在浏览器空闲时等待执行,否则会考虑进行机会性回流,如果发生这种情况, Firefox 在回流之前执行排队功能。
我发现该问题的唯一解决方案是强制重排元素,刷新对其所做的 CSS 更改,然后再删除“notransition”类。有多种方法可以做到这一点 - 请参阅此处。最接近“标准”的方法是读取offsetHeight
元素的属性。
那么,一种真正有效的解决方案是
someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions
这是一个 JS 小提琴,它说明了我在这里描述的三种可能的方法(一种成功的方法和两种不成功的方法):http:
//jsfiddle.net/2uVAA/131/