什么是最简洁的方式来暂时禁用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