无法让 JS 本机 animate() 使用高度

Can't get JS native animate() to work with height

我正在尝试使用本机 JS Element.animate() 执行 scrollUp 和 scrollDown。我希望元素从上到下平滑显示。我得到的是立即打开和延迟折叠。如果目前有更好的方法来做到这一点,我想知道,我仍然很好奇为什么这不起作用。

document.addEventListener('DOMContentLoaded', function() {
  document.getElementById('addNewScriptStep').onclick = function() {
    let list = document.getElementById('collapsibleActionList');
    let newHeight = '100%';
    if (list.dataset.iscollapsed == 'false') {
      newHeight = '0';
    }
    list.dataset.iscollapsed = !eval(list.dataset.iscollapsed);
    list.animate({
      height: newHeight
    }, {
      fill: 'forwards',
      duration: 500
    });
  };
});
#collapsibleActionList {
  overflow: hidden;
  height: 0;
  transition: height 0.5s;
}
<html>

<body>
  <a href="javascript:void(0)" id="addNewScriptStep" class=""> Add an action </a>
  <ul id="collapsibleActionList" data-iscollapsed="true">
    <li data-type="open_url">Open URL</li>
    <li data-type="href_to">Click link</li>
    <li data-type="click_element">Click element</li>
    <li data-type="insert_into">Insert into textbox</li>
    <li data-type="sleep">Sleep</li>
    <li data-type="checked">Check checkbox</li>
    <li data-type="unchecked">Uncheck checkbox</li>
    <li data-type="send_form">Submit form</li>
    <li data-type="if_element_is_defined">Continue if HTML contains element</li>
    <li data-type="if_element_is_not_defined">Continue if HTML doesn't contain element</li>
    <li data-type="if_text_is_defined">Continue if there is text</li>
    <li data-type="if_text_is_not_defined">Continue if there is no text</li>
  </ul>
</body>

</html>

编辑:我注意到在删除 CSS 转换 属性 后,列表不再折叠,尽管正在使用 {height: '0'}

调用动画函数

使用 max-height 而不是 height 你可以做到。

document.addEventListener('DOMContentLoaded', function() {
  document.getElementById('addNewScriptStep').onclick = function() {
    let list = document.getElementById('collapsibleActionList');
    let newHeight = '999px';
    if (list.dataset.iscollapsed == 'false') {
      newHeight = '0';
    }
    list.dataset.iscollapsed = !eval(list.dataset.iscollapsed);
    list.animate({
      maxHeight: newHeight
    }, {
      fill: 'forwards',
      duration: 500
    });
  };
});
#collapsibleActionList {
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.5s;
}
<body>
  <a href="javascript:void(0)" id="addNewScriptStep" class=""> Add an action </a>
  <ul id="collapsibleActionList" data-iscollapsed="true">
    <li data-type="open_url">Open URL</li>
    <li data-type="href_to">Click link</li>
    <li data-type="click_element">Click element</li>
    <li data-type="insert_into">Insert into textbox</li>
    <li data-type="sleep">Sleep</li>
    <li data-type="checked">Check checkbox</li>
    <li data-type="unchecked">Uncheck checkbox</li>
    <li data-type="send_form">Submit form</li>
    <li data-type="if_element_is_defined">Continue if HTML contains element</li>
    <li data-type="if_element_is_not_defined">Continue if HTML doesn't contain element</li>
    <li data-type="if_text_is_defined">Continue if there is text</li>
    <li data-type="if_text_is_not_defined">Continue if there is no text</li>
  </ul>
</body>

你可以用更简单的方法来做到这一点。如果你愿意?

const link = document.getElementById('addNewScriptStep')
const list = document.getElementById('collapsibleActionList')
link.addEventListener('click',()=>{
  list.classList.toggle('open')
})
#collapsibleActionList {
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.5s;
}
#collapsibleActionList.open {
  overflow: hidden;
  max-height: 999px;
  transition: max-height 0.5s;
}
<body>
  <a href="javascript:void(0)" id="addNewScriptStep" class=""> Add an action </a>
  <ul id="collapsibleActionList" data-iscollapsed="true">
    <li data-type="open_url">Open URL</li>
    <li data-type="href_to">Click link</li>
    <li data-type="click_element">Click element</li>
    <li data-type="insert_into">Insert into textbox</li>
    <li data-type="sleep">Sleep</li>
    <li data-type="checked">Check checkbox</li>
    <li data-type="unchecked">Uncheck checkbox</li>
    <li data-type="send_form">Submit form</li>
    <li data-type="if_element_is_defined">Continue if HTML contains element</li>
    <li data-type="if_element_is_not_defined">Continue if HTML doesn't contain element</li>
    <li data-type="if_text_is_defined">Continue if there is text</li>
    <li data-type="if_text_is_not_defined">Continue if there is no text</li>
  </ul>
</body>

height: 100% 在这种情况下并没有真正带来任何意义:因为它不依赖于某些父元素的高度,它基本上与 height: auto 相同并且您不能使用动画height:auto。现在,考虑到您已经在使用 .js,在为元素设置动画之前,您可以先将其固有高度设置为要设置动画的像素:

const ul = document.querySelector("ul")
const btn = document.querySelector("button")

//the important part:
ul.style.height = ul.scrollHeight + "px"

btn.addEventListener("click", ()=>ul.classList.toggle("open"))
ul{
  display: block;
  overflow: hidden;
  transition: height 1s;
  background: #ddd;
}

ul:not(.open){
  height: 0 !important;
}
<button>Click</button>
<ul>
  <li>Some elements</li>
  <li>To show</li>
</ul>