首页 > 解决方案 > 在元素样式上设置 .cssText 时转换不起作用?

问题描述

我有以下 CSS 片段:

.Test-Content {
  transition: height 2s;
}

和以下 HTML 代码:

<div id="mydiv" class="Test-Content">foo</div>

使用纯 JavaScript,我试图改变这样的高度div

myId = document.getElementById("mydiv");
myId.style.cssText = "height: 0;";

/* ... Lots of code and situations where the browser re-renders the page ... */

myId.style.cssText = "height: 100px";

这确实将div' 的高度从原来的任何内容更改为0,然后更改为100px,但没有任何动画,即立即。我不明白为什么会这样。毕竟,在它的类列表中有,所以div它的高度的任何变化都应该触发过渡。.Test-Content

有人可以解释为什么不是这样吗?

当我将其更改为以下(非常奇怪和令人担忧的)代码时,它按预期工作:

CSS:

.Test-Content-A {
  transition: height 2s;
  height: 0;
}
.Test-Content-B {
  transition: height 2s;
  height: 10px; /* or whatever number you prefer */
}

HTML:

<div id="mydiv" class="Test-Content-A Test-Content-B">foo</div>

JavaScript:(同上)

似乎style.cssText只有当该元素在其类列表中也有两个具有不同height属性的类时,我才能通过直接设置元素来触发转换。

我在 Firefox 和 Chrome 中遇到了这个问题(到目前为止还没有测试过其他的),在撰写本文时都处于当前的补丁级别。

标签: javascripthtmldomcss-transitions

解决方案


您可能会遇到一些事情,如下面的代码片段所示。第一次单击“展开”或“折叠”时,它不会动画,但之后单击“展开”或“折叠”会触发动画。

document.getElementById("expand").addEventListener('click', () => {
  myId = document.getElementById("mydiv");
  myId.style.cssText = "height: 100px";
});

document.getElementById("collapse").addEventListener('click', () => {
  myId = document.getElementById("mydiv");
  myId.style.cssText = "height: 0;";
});

document.getElementById("unset").addEventListener('click', () => {
  myId = document.getElementById("mydiv");
  myId.style.cssText = "";
});

document.getElementById("setandexpand").addEventListener('click', () => {
  myId = document.getElementById("mydiv");
  myId.style.cssText = "height: 0;";
  setTimeout(() => { myId.style.cssText = "height: 100px"; });
});
.Test-Content {
  transition: height 2s;
}
<div id="mydiv" class="Test-Content">foo</div>

<button id="expand">Expand</button>
<button id="collapse">Collapse</button>
<button id="unset">Unset</button>


<button id="setandexpand">Set and expand</button>

您可能遇到的问题:

1. CSS 只能从一个值过渡到一个值。

cssText = ""(初始值)变为cssText = "height: 100px"不动画。您可以通过单击“取消设置”然后单击“展开”或“折叠”来重现此内容。

2.如果在一段代码中多次设置CSS,浏览器只会处理最后一个。

浏览器在设置更改后不会立即呈现更改,而是在执行所有可执行 JavaScript 和根据设置的内容更新页面之间切换。您可以通过将其分为两个离散步骤来解决此问题。最好的可能是style="height: 0"在 HTML 中设置或添加一个高度为零的类。

否则,您可以执行以下操作:

myId.style.cssText = "height: 0";
setTimeout(() => { myId.style.cssText = "height: 100px"; });

此代码将高度设置为零,让浏览器更新样式,然后执行将高度设置为 100 像素的新代码,浏览器可以对其进行动画处理。当然,你只需要调用cssText = "height: 0",因为一旦它被渲染,浏览器就可以动画了。

您可以通过单击“取消设置”然后单击“设置并展开”在代码段中看到这一点。该元素将立即减小到零,然后扩展为 100px。多次单击似乎不会做任何事情,因为每次浏览器都会开始动画到零,然后在几毫秒内开始动画回到 100px。


推荐阅读