在将 appendChild 与本机 javascript 一起使用后,如何更新对 HTML 元素的引用

How do I update the reference to an HTML element after I used appendChild with native javascript

我正在使用本机 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 来定位元素或添加 class 并使用该 class 遍历所有元素并定位最后一个元素,但这些方法感觉很丑陋。

我想知道当您将某些内容附加到 DOM 以定位您刚刚附加的内容时是否有某种回调,或者我这样做的逻辑是否完全错误。

FIDDLE

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

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

If the given child is a DocumentFragment, the entire contents of the DocumentFragment are moved into the child list of the specified parent node.

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

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

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

所以,一旦添加了documentFragment,就无法一次性全部删除。

如果片段保证只包含一个元素,就像在您的示例中一样,那么 select 那个元素并附加 代替(然后您可以正确地参考其 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>

while 循环中附加节点是不必要的:innerHTML 已经为您完成了。

var createHTML = function(htmlStr) {
    var temp = document.createElement('div');
    temp.innerHTML = htmlStr;
    return temp;
}

这样 - 没有 DOM 片段 - 在超时后删除元素按预期工作。