什么是最干净的方法来临时禁用CSS转换效果? [英] What is the cleanest way to disable CSS transition effects temporarily?

查看:187
本文介绍了什么是最干净的方法来临时禁用CSS转换效果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a DOM element with some/all of the following effects applied:

#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插件来调整这个元素的大小,我需要禁用这些效果暂时,所以我可以调整它的顺利。

I am writing a jQuery plugin that is resizing this element, I need to disable these effects temporarily so I can resize it smoothly.

暂时禁用这些效果(然后重新启用它们)的最优雅的方法是,因为它们可能从父母处申请,或根本不应用。

What is the most elegant way of disabling these effects temporarily (and then re-enabling them), given they may be applied from parents or may not be applied at all.

推荐答案

简答



/ strong>

Short Answer

Use this CSS:

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

strong>

Plus either this JS (with jQuery)...

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

...或等效JavaScript使用原始DOM函数或任何其他框架

... or equivalent JavaScript using raw DOM functions or whatever other framework you're working with.

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

This is actually a fairly subtle problem.

首先,你可能想创建一个'notransition'类,你可以应用到元素来设置他们的 * - transition CSS属性 none 。例如:

First up, you probably want to create a 'notransition' class that you can apply to elements to set their *-transition CSS attributes to none. For instance:

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

code> -ms-transition 在那里,你不需要它。第一个版本的Internet Explorer支持过渡 是IE 10,支持)

(Minor aside - note the lack of an -ms-transition in there. You don't need it. The first version of Internet Explorer to support transitions at all was IE 10, which supported them unprefixed.)

但这只是风格,而且是简单的一点。当你来尝试和使用这个类,你会陷入陷阱。陷阱是,像这样的代码不会工作,你可能天真地期望的方式:

But that's just style, and is the easy bit. When you come to try and use this class, you'll run into a trap. The trap is that code like this won't work the way you might naively expect:

// 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')

可能认为高度的变化不会被动画化,因为它发生在'nottransition'类被应用时。在现实中,虽然,动画,至少在所有现代浏览器我试过。问题是浏览器缓存所需的样式更改,直到JavaScript完成执行,然后在单个回流中进行所有更改。结果,它进行回流,其中没有净变化是否启用转换,但是高度有净变化。因此,它会动画高度的变化。

Naively, you might think that the change in height won't be animated, because it happens while the 'notransition' class is applied. In reality, though, it will be animated, at least in all modern browsers I've tried. The problem is that the browser is caching the styling changes that it needs to make until the JavaScript has finished executing, and then making all the changes in a single reflow. As a result, it does a reflow where there is no net change to whether or not transitions are enabled, but there is a net change to the height. Consequently, it animates the height change.

你可能认为一个合理和干净的方法来解决这个问题是将'notransition'类移除1毫秒超时,像这样:

You might think a reasonable and clean way to get around this would be to wrap the removal of the 'notransition' class in a 1ms timeout, like this:

// 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(在慢和快的机器上),你有时(似乎在随机)获得与使用naive方法相同的行为。我猜这是因为JavaScript执行可能足够慢,超时功能等待浏览器空闲时执行,否则将考虑做一个机会性的回流,如果发生这种情况, Firefox在回流之前执行排队的函数。

but this doesn't reliably work either. I wasn't able to make the above code break in WebKit browsers, but on Firefox (on both slow and fast machines) you'll sometimes (seemingly at random) get the same behaviour as using the naive approach. I guess the reason for this is that it's possible for the JavaScript execution to be slow enough that the timeout function is waiting to execute by the time the browser is idle and would otherwise be thinking about doing an opportunistic reflow, and if that scenario happens, Firefox executes the queued function before the reflow.

我发现问题的唯一解决方案是强制元素的回流,刷新对它的CSS更改,在删除​​'notransition'类之前。有多种方法可以执行此操作 - 请参见此处对于一些。最接近的事情是标准的做法是读取元素的 offsetHeight 属性。

The only solution I've found to the problem is to force a reflow of the element, flushing the CSS changes made to it, before removing the 'notransition' class. There are various ways to do this - see here for some. The closest thing there is to a 'standard' way of doing this is to read the offsetHeight property of the element.

$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/

Here's a JS fiddle that illustrates the three possible approaches I've described here (both the one successful approach and the two unsuccessful ones): http://jsfiddle.net/2uVAA/35/

这篇关于什么是最干净的方法来临时禁用CSS转换效果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆