【问题标题】:Javascript - How to replace multiple HTML nodesJavascript - 如何替换多个 HTML 节点
【发布时间】:2019-11-23 00:12:08
【问题描述】:

我正在构建一个电子邮件构造函数,当用户保存模板时,我只是将 HTML 发送到服务器。但我需要删除 drap & drop 元素才能将其发送到服务器。

我不太擅长 DOM 操作,所以我不知道从哪里开始。

这是我的 HTML:

<table>
  <tbody>
    <tr>
      <th>
        <div class="components-drop-area">
          <p>aa</p>
          <p>bb</p>
        </div>
      </th>
    </tr>
    <tr>
      <th>
        <div class="components-drop-area">
          <p>cc</p>
          <p>dd</p>
        </div>
      </th>
    </tr>
  </tbody>
</table>

我需要删除所有 .components-drop-area div。类似的东西:

<table>
  <tbody>
    <tr>
      <th>
        <p>aa</p>
        <p>bb</p>
      </th>
    </tr>
    <tr>
      <th>
        <p>cc</p>
        <p>dd</p>
      </th>
    </tr>
  </tbody>
</table>

我在这里停止了我的代码:

var table = document.querySelector('table').cloneNode(true)

let dropAreas = table.querySelectorAll('.components-drop-area')

console.log(table, dropAreas)

如何在保留内容的同时循环和删除所需元素?

【问题讨论】:

标签: javascript html dom


【解决方案1】:

一种方法是简单地将parentNodeinnerHTMLs 替换为.components-drop-area innerHTMLs:

let dropAreas = document.querySelectorAll('.components-drop-area');
for (let i = 0; i < dropAreas.length; i++) {
  dropAreas[i].parentNode.innerHTML = dropAreas[i].innerHTML;
}

// The <div> contents have now been extracted, and the <div> elements removed
console.log(document.querySelector('table').innerHTML);
<table>
  <tbody>
    <tr>
      <th>
        <div class="components-drop-area">
          <p>aa</p>
          <p>bb</p>
        </div>
      </th>
    </tr>
    <tr>
      <th>
        <div class="components-drop-area">
          <p>cc</p>
          <p>dd</p>
        </div>
      </th>
    </tr>
  </tbody>
</table>

【讨论】:

  • 这里唯一的警示故事是,您将破坏 DOM 中未由这些元素的字符串表示形式反映的任何状态。在这个例子中这可能没什么大不了,但在另一个现实世界的例子中,它可能很重要。
【解决方案2】:

这是对 James 的原版 JS 实现的改编,应该可以工作

for (const node of document.querySelectorAll("table .components-drop-area")) {
  const parent = node.parentNode;
  while (node.children.length>0) {
    let child = node.children[0];
    node.removeChild(child);
    parent.insertBefore(child, node);
  }
  parent.removeChild(node);
}

循环遍历元素很棘手,因为我们在迭代期间修改了集合

for (const node of document.querySelectorAll("table .components-drop-area")) {
  const parent = node.parentNode;
  while (node.children.length>0) {
    let child = node.children[0];
    node.removeChild(child);
    parent.insertBefore(child, node);
  }
  parent.removeChild(node);
}

// The <div> contents have now been extracted, and the <div> elements removed
console.log(document.querySelector('table').innerHTML);
<table>
  <tbody>
    <tr>
      <th>
        <div class="components-drop-area">
          <p>aa</p>
          <p>bb</p>
        </div>
      </th>
    </tr>
    <tr>
      <th>
        <div class="components-drop-area">
          <p>cc</p>
          <p>dd</p>
        </div>
      </th>
    </tr>
  </tbody>
</table>

【讨论】:

    【解决方案3】:

    如果你想使用 vanilla DOM 操作,你必须从选定的 div 元素中获取每个子元素,并将它们插入到该节点的父元素中,使用选定的 div 本身作为参考,然后再将其删除。每个 DOM 节点都有对其父节点和子节点的引用,因此您可以对每个选定节点执行所有操作,如下所示:

      for (const node of document.querySelectorAll("table .components-drop-area")) {
        const parent = node.parentNode;
        const children = Array.from(node.children);
        for (const child of children) {
          node.removeChild(child);
          parent.insertBefore(child, node);
        }
        parent.removeChild(node);
      }
    

    【讨论】:

    • A+ 用于 vanilla DOM 操作——尽管这里的输出不是我认为你想要的。罪魁祸首 - node.children 上的 for 循环在您迭代它时会受到修改子级的影响 - 所以您只移动一些节点
    • 好收获。子 HTMLCollection 属性确实随着 DOM 更改而实时更新。为了解决这个问题,我对我的回答做了一些修改。
    【解决方案4】:

    使用jQuery 的优雅解决方案是:

    $('.components-drop-area').contents().unwrap();
    console.log(document.querySelector('table').innerHTML);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <table>
      <tbody>
        <tr>
          <th>
            <div class="components-drop-area">
              <p>aa</p>
              <p>bb</p>
            </div>
          </th>
        </tr>
        <tr>
          <th>
            <div class="components-drop-area">
              <p>cc</p>
              <p>dd</p>
            </div>
          </th>
        </tr>
      </tbody>
    </table>

    注意事项:

    【讨论】:

    猜你喜欢
    • 2017-04-23
    • 2010-11-17
    • 2021-10-18
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多