用outerHTML替换元素并立即访问新创建的元素

sam*_*ris 4 html javascript dom

我通过将 DOM 元素的内容替换为outerHTML. 该技巧有效,但我需要立即访问新创建的 DOM 元素。

不幸的是,元素的创建<x>和内容的生成var code不在我的控制之下。

var code, e;

(function () {
  /**
   * Things done inside this IIFE is not under my control
   */
  code =
    '<div style="border: 1px solid black;">' +
    '  <span>I </span>' +
    '  <span>want </span>' +
    '  <span>to </span>' +
    '  <span>access </span>' +
    '  <span>all </span>' +
    '  <span>these </span>' +
    '  <span>spans.</span>' +
    '</div>';
  e = document.getElementById('replace_this');
}());

e.outerHTML = code;

// by this point, element e is replaced with newly added HTML. Let's do
// an alert to make sure
alert('Check the document. New HTML is rendered.');

var spans = e.getElementsByTagName('span'); // oops! empty collection
alert(spans.length); // alerts 0
alert(e.outerHTML); // alerts '<x></x>'
Run Code Online (Sandbox Code Playgroud)
<div id="container" style="padding: 20px; border: 1px dashed grey;">
  <div>Don't replace this.</div>
  <x id="replace_this"></x>
  <div>Don't replace this either.</div>
</div>
Run Code Online (Sandbox Code Playgroud)

该行为在MDN 的注释中进行了outerHTML解释:

此外,虽然元素将在文档中被替换,但设置了 outerHTML 属性的变量仍将保留对原始元素的引用

所以我的问题是,如何在替换旧元素后立即访问新添加的元素?

PS:outerHTML如果有另一种方法可以用来替换元素然后访问新创建的元素,我准备放弃。

sam*_*ris 6

最后我决定在之前插入新元素,使用insertAdjacentHTML,通过调用获取新元素previousSibling,然后使用parentElement.removeChild

var code, e;

(function () {
  /**
   * Things done inside this IIFE is not under my control
   */
  code =
    '<div style="border: 1px solid black;">' +
    '  <span>I </span>' +
    '  <span>want </span>' +
    '  <span>to </span>' +
    '  <span>access </span>' +
    '  <span>all </span>' +
    '  <span>these </span>' +
    '  <span>spans.</span>' +
    '</div>';
  e = document.getElementById('replace_this');
}());

// insert the new element just before <x>
e.insertAdjacentHTML('beforeBegin', code);
// now <x>'s previousSibling should be the newly added element
var new_elem = e.previousSibling;
// get rid of <x>
e.parentElement.removeChild(e);

// by this point, element e is replaced with newly added HTML. Let's do
// an alert to make sure
alert('Check the document. New HTML is rendered.');

var spans = new_elem.getElementsByTagName('span'); 
alert(spans.length); // alerts 7
alert(new_elem.outerHTML); // alerts contents of new element
Run Code Online (Sandbox Code Playgroud)
<div id="container" style="padding: 20px; border: 1px dashed grey;">
  <div>Don't replace this.</div>
  <x id="replace_this"></x>
  <div>Don't replace this either.</div>
</div>
Run Code Online (Sandbox Code Playgroud)