首页 > 解决方案 > 将 appendChild 与本机 javascript 一起使用后,如何更新对 HTML 元素的引用

问题描述

我正在使用本机 javascript 将一个元素附加到我的 DOM,该元素在 X 秒后消失。

为了附加元素,我创建了一个带有函数的文档片段,createHTML然后将此元素附加到我的容器元素中。

var elementHTML = '<div>Test element appended</div>';
    elementHTML = createHTML(elementHTML);      
document.getElementById('append-container').appendChild(elementHTML);

然后我设置一个超时,在 x 秒后从 DOM 中删除元素

setTimeout(function() {
    elementHTML.parentNode.removeChild(elementHTML);
}, 2000, elementHTML); 

现在这将不起作用,因为当您使用 appendChild 时,元素会被移动并且对元素的引用会丢失。我正在寻找一种方法来更新对elementHTML我刚刚附加到 DOM 的元素的引用。

基本上我正在寻找不使用 jQuery 的 jQuery 参考功能。

我可以使用随机生成的 ID 来定位元素或添加一个类并循环遍历该类的所有元素并定位最后一个,但这些方法感觉很难看。

我想知道当您将某些内容附加到 DOM 以针对您刚刚附加的内容时是否存在某种回调,或者我的逻辑是否完全错误。

小提琴

标签: javascriptappendchild

解决方案


问题是 aDocumentFragment会将片段的内容移动到 DOM 中的新位置,但片段本身将仍然是片段,不直接附加到任何东西:

https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild

如果给定的子节点是 DocumentFragment,则 DocumentFragment 的全部内容被移动到指定父节点的子节点列表中。

毕竟,否则,如果 HTML 字符串是

<div>Test element appended</div><div>Test element 2 appended</div>

附件可以documentFragment指什么?它不能只是一个或另一个<div>,也不能是父元素(它已经在 DOM 中,并且不是用片段创建的)。

因此,一旦documentFragment附加了 a ,就无法一次性将其全部删除。

如果片段保证只包含一个元素,就像在你的例子中一样,那么选择那个元素并附加(然后你可以正确地引用它parentNode)。

// though using a documentFragment in the first place is a bit odd
// if you're not going to append it

var createHTML = function(htmlStr) {
  var frag = document.createDocumentFragment(),
    temp = document.createElement('div');
  temp.innerHTML = htmlStr;
  while (temp.firstChild) {
    frag.appendChild(temp.firstChild);
  }
  return frag;
}

var appendItems = function() {
  const elementHTML = '<div>Test element appended</div>';
  const fragment = createHTML(elementHTML);
  const fragmentElm = fragment.children[0];
  document.getElementById('append-container').appendChild(fragmentElm);
  setTimeout(function() {
    fragmentElm.parentNode.removeChild(fragmentElm);
  }, 2000, elementHTML);
}

document.getElementById('test-append').addEventListener('click', appendItems);
<div id="append-container">

</div>

<button id="test-append">
  Test
</button>

另一种选择是遍历所有附加的节点和.remove()它们:

var createHTML = function(htmlStr) {
  var frag = document.createDocumentFragment(),
    temp = document.createElement('div');
  temp.innerHTML = htmlStr;
  while (temp.firstChild) {
    frag.appendChild(temp.firstChild);
  }
  return frag;
}

var appendItems = function() {
  const elementHTML = '<div>Test element appended</div><div>Test element 2 appended</div>';
  const fragment = createHTML(elementHTML);
  const fragmentElms = [...fragment.children];
  const container = document.getElementById('append-container');
  fragmentElms.forEach((elm) => {
    container.appendChild(elm);
  });
  setTimeout(function() {
    fragmentElms.forEach((elm) => {
      elm.remove();
    });
  }, 2000, elementHTML);
}

document.getElementById('test-append').addEventListener('click', appendItems);
<div id="append-container">

</div>

<button id="test-append">
  Test
</button>


推荐阅读