什么是最简洁的方式来暂时禁用CSS过渡效果?

我有一个应用了以下某些/所有下列效果的DOM元素:

#elem { -webkit-transition: height 0.4s ease; -moz-transition: height 0.4s ease; -o-transition: height 0.4s ease; transition: height 0.4s ease; } 

我正在写一个正在调整这个元素的jQuery插件,我需要暂时禁用这些效果,所以我可以顺利地调整它。

暂时禁用这些效果(然后重新启用它们)的最优雅的方式是什么,因为它们可能是从父母那里申请的,或者可能根本不适用。

简答

使用这个CSS:

 .notransition { -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important; } 

再加上这个JS(与jQuery)…

 $someElement.addClass('notransition'); // Disable transitions doWhateverCssChangesYouWant($someElement); $someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes $someElement.removeClass('notransition'); // Re-enable transitions 

…或使用原始DOMfunction或任何其他您正在使用的框架的等效JavaScript。

说明

这实际上是一个相当微妙的问题。

首先,您可能希望创build一个“notransition”类,您可以将其应用于元素以将它们的*-transition CSS属性设置为none 。 例如:

 .notransition { -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important; } 

(小调 – 注意在那里缺less一个-ms-transition ,你不需要它,支持转换的第一个IE浏览器版本是IE 10,它支持它们没有前缀)。

但这只是一种风格,而且很简单。 当你来试试这个课程时,你会遇到一个陷阱。 陷阱是,像这样的代码不会像你天真地期望的那样工作:

 // Don't do things this way! It doesn't work! $someElement.addClass('notransition') $someElement.css('height', '50px') // just an example; could be any CSS change $someElement.removeClass('notransition') 

天真地说,你可能会认为高度的变化不会生动,因为它发生在“非转换”类被应用的时候。 但事实上,至less在我尝试过的所有现代浏览器中,它将会是animation的。 问题是浏览器正在caching它需要做的样式更改,直到JavaScript完成执行,然后在单个回stream中进行所有更改。 因此,在没有变化是否启用的情况下,它会进行回stream,但高度有一个净变化。 因此,它激发高度变化。

你可能会认为一个合理而干净的方法来解决这个问题,就是在1ms的超时时间内将“notransition”类去掉,如下所示:

 // Don't do things this way! It STILL doesn't work! $someElement.addClass('notransition') $someElement.css('height', '50px') // just an example; could be any CSS change setTimeout(function () {$someElement.removeClass('notransition')}, 1); 

但是这也不可靠。 我无法在WebKit浏览器中使上述代码中断,但是在Firefox上(在慢速和快速的机器上),您有时(似乎是随机的)获得与使用朴素方法相同的行为。 我想这样做的原因是,JavaScript执行速度可能会很慢,以至于在浏览器空闲时等待执行超时function,否则会考虑进行机会回stream,如果发生这种情况, Firefox在重排之前执行排队function。

我发现问题的唯一解决scheme是强制重排元素,刷新对其进行的CSS更改,然后删除“notransition”类。 有很多种方法可以做到这一点 – 请参阅这里的一些。 最接近这样做的“标准”方式是读取元素的offsetHeight属性。

其中一个解决scheme实际上是有效的

 $someElement.addClass('notransition'); // Disable transitions doWhateverCssChangesYouWant($someElement); $someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes $someElement.removeClass('notransition'); // Re-enable transitions 

这是一个JS小提琴,说明了我在这里描述的三种可能的方法(一个成功的方法和两个不成功的方法): http : //jsfiddle.net/2uVAA/35/

添加一个阻塞转换的额外CSS类,然后将其删除以返回到之前的状态。 这使得CSS和JQuery代码变得简单而且易于理解。

CSS

 .notransition { -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; -ms-transition: none !important; transition: none !important; } 

!important是增加了确保这个规则会有更多的“权重”,因为ID通常比类更具体。

JQuery

 $('#elem').addClass('notransition'); // to remove transition $('#elem').removeClass('notransition'); // to return to previouse transition 

我会主张像DaneSoulbuild议的那样禁用animation,但是把开关全局化:

 /*kill the transitions on any descendant elements of .notransition*/ .notransition * { -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; -ms-transition: none !important; transition: none !important; } 

.notransition然后可以应用到body元素,有效地覆盖页面上的任何过渡animation:

 $('body').toggleClass('notransition'); 

对于一个纯粹的JS解决scheme(没有CSS类),只需设置transition'none' 。 要恢复CSS中指定的转换,请将transition设置为空string。

 // Remove the transition elem.style.transition = 'none'; // Restore the transition elem.style.transition = ''; 

如果您使用的是供应商前缀,则还需要设置这些前缀。

 elem.style.webkitTransition = 'none' 

你可以使用这个CSS代码禁用页面中所有元素的animation,转换和转换

 var style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = '* {' + '/*CSS transitions*/' + ' -o-transition-property: none !important;' + ' -moz-transition-property: none !important;' + ' -ms-transition-property: none !important;' + ' -webkit-transition-property: none !important;' + ' transition-property: none !important;' + '/*CSS transforms*/' + ' -o-transform: none !important;' + ' -moz-transform: none !important;' + ' -ms-transform: none !important;' + ' -webkit-transform: none !important;' + ' transform: none !important;' + ' /*CSS animations*/' + ' -webkit-animation: none !important;' + ' -moz-animation: none !important;' + ' -o-animation: none !important;' + ' -ms-animation: none !important;' + ' animation: none !important;}'; document.getElementsByTagName('head')[0].appendChild(style); 

我认为你可以创build一个单独的CSS类,你可以在这些情况下使用:

 .disable-transition { -webkit-transition: none; -moz-transition: none; -o-transition: color 0 ease-in; -ms-transition: none; transition: none; } 

然后在jQuery中,您可以像这样切换类:

 $('#<your-element>').addClass('disable-transition'); 

 $('#elem').css('-webkit-transition','none !important'); 

在你的js杀了吗?

明显重复每个。

我会在你的CSS中有这样一个类:

 .no-transition { -webkit-transition: none; -moz-transition: none; -o-transition: none; -ms-transition: none; transition: none; } 

然后在你的jQuery中:

 $('#elem').addClass('no-transition'); //will disable it $('#elem').removeClass('no-transition'); //will enable it