236

我有一个应用了以下部分/全部效果的 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 插件,我需要暂时禁用这些效果,以便我可以顺利调整它的大小。

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

4

11 回答 11

540

简答

使用这个 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

或者这个带有 jQ​​uery 的 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”类,您可以将其应用于元素以将其*-transitionCSS 属性设置为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/

于 2013-05-15T22:08:22.953 回答
22

添加一个额外的 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 比 class 更具体。

查询

$('#elem').addClass('notransition'); // to remove transition
$('#elem').removeClass('notransition'); // to return to previouse transition
于 2012-06-21T05:31:39.083 回答
22

我会提倡按照 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; 
} 

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

$('body').toggleClass('notransition');
于 2012-06-21T06:45:16.613 回答
11

对于纯 JS 解决方案(无 CSS 类),只需transition'none'. 要恢复 CSS 中指定的过渡,请将 设置transition为空字符串。

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

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

如果您使用供应商前缀,您也需要设置这些前缀。

elem.style.webkitTransition = 'none'
于 2015-05-14T01:49:25.140 回答
11

您可以使用此 css 代码禁用页面中所有元素的动画、过渡、转换

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);
于 2015-10-07T09:12:35.020 回答
2

我认为您可以创建一个单独的 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');
于 2012-06-21T05:30:43.950 回答
1

如果您想要一个简单的无 jquery 解决方案来防止所有转换:

  1. 添加这个CSS:
body.no-transition * {
  transition: none !important;
}
  1. 然后在你的js中:
document.body.classList.add("no-transition");

// do your work, and then either immediately remove the class:

document.body.classList.remove("no-transition");

// or, if browser rendering takes longer and you need to wait until a paint or two:

setTimeout(() => document.body.classList.remove("no-transition"), 1);

// (try changing 1 to a larger value if the transition is still applying)
于 2020-04-23T04:58:24.077 回答
1

这是对我来说很容易工作的解决方法。这不是问题的直接答案,但仍然可以帮助某人。

而不是创建notransition应该取消转换的类

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

我创建了moveTransition班级

.moveTransition {
      -webkit-transition: left 3s, top 3s;
      -moz-transition: left 3s, top 3s;
      -o-transition: left 3s, top 3s;
      transition: left 3s, top 3s;
}

然后我用js将这个类添加到元素中

element.classList.add("moveTransition")

后来在 setTimeout 中,我删除了它

element.classList.remove("moveTransition")

我无法在不同的浏览器中对其进行测试,但在 chrome 中它可以完美运行

于 2020-07-26T18:02:06.643 回答
0

如果你想从当前网页中删除 CSS 过渡、转换和动画,你可以执行我写的这个小脚本(在你的浏览器控制台中):

let filePath = "https://dl.dropboxusercontent.com/s/ep1nzckmvgjq7jr/remove_transitions_from_page.css";
let html = `<link rel="stylesheet" type="text/css" href="${filePath}">`;
document.querySelector("html > head").insertAdjacentHTML("beforeend", html);

它使用 vanillaJS 来加载这个 css 文件。如果您想在刮板(Ruby-Selenium)的上下文中使用它,这里还有一个 github 存储库:remove-CSS-animations-repo

于 2019-10-25T13:02:19.570 回答
-2

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

在你的js中杀了它?

显然对每个重复。

于 2012-06-21T05:25:40.957 回答
-3

我会在你的 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
于 2012-06-21T05:31:44.167 回答