javascript element.remove() 不删除 dom

javascript element.remove() not remove dom

element.remove() 好像很奇怪。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
  <script>
    class View {
      constructor() {
        this.parent = document.querySelector('#root')
      }
      template() {
        return `
        <div>Random Num</div>
        <div>${Math.random()}</div>
        <button type='button'>Reset Random Num</button>
      `
      }
      render() {
        const templateElement = document.createElement('template')
        templateElement.innerHTML = this.template()
        templateElement.content
          .querySelector('button')
          .addEventListener('click', () => {
            this.rerender()
          })
        this.parent.append(templateElement.content)
      }
      rerender() {
        this.parent.childNodes.forEach((item) => {
          // here is the problem
          item.remove()
        })
        // const templateElement = document.createElement('template')
        // templateElement.innerHTML = this.template()
        // this.parent.append(templateElement.content)
      }
    }
    const viewIns = new View()
    viewIns.render()
  </script>
</html>

当我点击按钮时,doms 根本没有被移除,然后我再次点击按钮,只有 div包含剩余的随机数,我真的很困惑为什么会这样。

childNodes returns 现场合集。使用实时集合可能不直观,因为它们可以在您迭代它们时 自己发生变异 并让您失望。在这里,您 .remove() 创建一个文本节点,然后 <div>Random Num</div> 立即成为集合中的第 0 个索引。然后您转到集合中的第一个索引,这是另一个文本节点。该过程重复几次,删除所有文本节点,但不删除任何元素。

先将childNodes转成数组,这样集合在迭代时不会改变。

[...this.parent.childNodes].forEach((item) => {

class View {
  constructor() {
    this.parent = document.querySelector('#root')
  }
  template() {
    return `
        <div>Random Num</div>
        <div>${Math.random()}</div>
        <button type='button'>Reset Random Num</button>
      `
  }
  render() {
    const templateElement = document.createElement('template')
    templateElement.innerHTML = this.template()
    templateElement.content
      .querySelector('button')
      .addEventListener('click', () => {
        this.rerender()
      })
    this.parent.append(templateElement.content)
  }
  rerender() {
    [...this.parent.childNodes].forEach((item) => {
      item.remove()
    })
    // const templateElement = document.createElement('template')
    // templateElement.innerHTML = this.template()
    // this.parent.append(templateElement.content)
  }
}
const viewIns = new View()
viewIns.render()
<div id="root"></div>

或者,更简单的方法是将父级的 .innerHTML 设置为空字符串。

this.parent.innerHTML = '';