javascript - 在元素样式上设置 .cssText 时过渡不起作用?

标签 javascript html dom css-transitions

我有以下 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 中遇到了这个问题(到目前为止还没有测试其他的),在撰写本文时都处于当前补丁级别。

最佳答案

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

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 和根据所有设置更新页面之间切换。您可以通过将其分成两个独立的步骤来解决这个问题。最好的可能是在 HTML 中设置 style="height: 0" 或添加一个高度为零的类。

否则,你可以这样做:

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

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

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

关于javascript - 在元素样式上设置 .cssText 时过渡不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58824025/

相关文章:

javascript - 如何在运行长 javascript 代码时处理用户输入事件?

javascript - html 的静音/取消静音图标

javascript - jQuery 将 Href 匹配到 div ID

javascript - 是否可以在不循环的情况下在其父节点中获取元素的数字索引?

javascript - 如何避免jQgrid初始AJAX请求?

javascript - Lodash 与过滤器中的 OR 逻辑

javascript - Raphaël.js 动画 resume() 在设置时失败

javascript - 如何在此 PHP 页面中用简单的 HTML 选择替换此价格 slider ?选择选项可以传递 2 个值(最低价格和最高价格)吗?

dom - 无法操作 React 组件中的 DOM

javascript - 递归删除javascript中的所有嵌套节点