临时禁用CSS过渡效果的最简洁方法是什么?

Sam*_*ron 192 javascript css jquery

我有一个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;
}
Run Code Online (Sandbox Code Playgroud)

我正在编写一个调整此元素大小的jQuery插件,我需要暂时禁用这些效果,以便我可以顺利调整大小.

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

Mar*_*ery 450

简答

使用这个CSS:

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  transition: none !important;
}
Run Code Online (Sandbox Code Playgroud)

再加上这个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
Run Code Online (Sandbox Code Playgroud)

或者这个带有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
Run Code Online (Sandbox Code Playgroud)

...或使用您正在使用的任何其他库或框架的等效代码.

说明

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

首先,您可能想要创建一个"notransition"类,您可以将其应用于元素以将其*-transitionCSS属性设置为none.例如:

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  transition: none !important;
}
Run Code Online (Sandbox Code Playgroud)

(次要一边-注意缺少的-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')
Run Code Online (Sandbox Code Playgroud)

天真地,你可能会认为高度的变化不会被动画化,因为它会在应用'notransition'类时发生.但实际上,它被动画化,至少在我尝试的所有现代浏览器中都是如此.问题是浏览器正在缓存它需要进行的样式更改,直到JavaScript完成执行,然后在单个重排中进行所有更改.因此,它会进行回流,其中对是否启用转换没有净更改,但高度会发生净变化.因此,它可以激活高度变化.

你可能认为一个合理而干净的解决方法就是在1ms的超时时间内删除'notransition'类,如下所示:

// 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);
Run Code Online (Sandbox Code Playgroud)

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

我发现这个问题的唯一解决办法是强制元素的回流,冲洗去掉"notransition"课前发微博,CSS的变化.有很多方法可以做到这一点 - 请参阅此处.最接近"标准"方法的方法是读取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
Run Code Online (Sandbox Code Playgroud)

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

  • Excelente回答.干得好,并且因为我想出了同样的问题而受到赞赏.如果我只想删除一种类型的转换怎么办? (6认同)
  • 您的解决方案是正确的,但对于那些寻找更多背景信息的人:http://stackoverflow.com/a/31862081/1026 (2认同)
  • *轻微*小一点,IE10是IE的第一个*稳定*版本,带有无前缀的转换.预发布版本(不包括Release Preview)需要-ms-前缀用于转换,以及一系列其他内容.我怀疑,这是今天出现-ms-前缀的原因之一.另一方面,当然更有可能的原因是我们都知道并喜欢供应商前缀的常见货物崇拜. (2认同)
  • 为没有 offsetHeight 属性的 SVG 元素设置动画时,回流技巧似乎不起作用;setTimeout 有效。 (2认同)

Dan*_*oul 17

添加一个阻止转换的其他CSS类,然后将其删除以返回到先前的状态.这使得CSS和JQuery代码简短,易于理解.

CSS:

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  -ms-transition: none !important;
  transition: none !important;
}
Run Code Online (Sandbox Code Playgroud)

!important 添加以确保此规则将具有更多"权重",因为ID通常比类更具体.

JQuery:

$('#elem').addClass('notransition'); // to remove transition
$('#elem').removeClass('notransition'); // to return to previouse transition
Run Code Online (Sandbox Code Playgroud)

  • -1因为这还不足以解决Chrome或Firefox中的问题 - 如果我有Javascript添加类,进行更改并删除类,有时更改*仍然是*动画.我已经花了最后一两个小时研究这个问题并稍后发布一个答案,其中小提示显示天真方法失败的情况,加上一个整洁的黑客通过强制重新进行更改和删除之间的解决方案来修复解决方案'notransition'课程. (5认同)
  • 我建议不要使用 !important 除非绝对必要。以后可能会引起很多头痛。我已经在没有它的情况下尝试过了,只要你遵循 CSS 的级联规则,它仍然可以正常工作。 (2认同)

o.v*_*.v. 16

我会提倡DaneSoul建议的禁用动画,但要使交换机全局化:

/*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; 
} 
Run Code Online (Sandbox Code Playgroud)

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

$('body').toggleClass('notransition');
Run Code Online (Sandbox Code Playgroud)

  • 实际上这是完美的选择imo.特别是*帮助很多,确保没有触发任何子动画.谢谢,upvoted. (2认同)
  • 性能方面,我完全不能指望这会是个好主意。“哦,只需将其应用于页面上的所有内容,这会让事情变得更容易!” (2认同)
  • 应该同时选择“.notransition”和“.notransition *”才能完全有效。 (2认同)
  • 我建议不要使用 !important 除非绝对必要。以后可能会引起很多头痛。我已经在没有它的情况下尝试过了,只要你遵循 CSS 的级联规则,它仍然可以正常工作。 (2认同)

Tho*_*ham 8

对于纯JS解决方案(没有CSS类),只需设置transition'none'.要恢复CSS中指定的转换,请将其设置transition为空字符串.

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

// Restore the transition
elem.style.transition = '';
Run Code Online (Sandbox Code Playgroud)

如果您使用的是供应商前缀,则还需要设置它们.

elem.style.webkitTransition = 'none'
Run Code Online (Sandbox Code Playgroud)


Ali*_*Ali 8

您可以使用此css代码禁用页面中所有元素的动画,转换和trasforms

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);
Run Code Online (Sandbox Code Playgroud)