将element替换为outerHTML并立即访问新创建的元素



我通过将其内容替换为outerHTML来替换DOM元素。这个技巧有效,但是我需要立即访问新创建的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>'
<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>

该行为在MDN关于outerHTML的注释中有解释:

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

的引用。

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

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

最后我决定在之前插入新元素,使用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
<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>

为什么不给出生成的div和id?然后可以在新元素上gettelementbyid。

var code =
    '<div id="newElement" 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>';
var e = document.createElement('x');
document.getElementById('container').appendChild(e);
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.');
e = getElementById('newElement'); // reassign e to the new div
var spans = e.getElementsByTagName('span'); 
alert(spans.length);
alert(e.outerHTML);

我设法得到它使用以下javascript:

var 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>';
var e = document.createElement('x');
document.getElementById('container').appendChild(e);
e.outerHTML = code;
var spans = e.getElementsByTagName('span'); // oops! empty collection

这些是我的改动:

/**
 * Return direct children elements.
 *
 * @param {HTMLElement}
 * @return {Array}
 */
function elementChildren(element) {
    var childNodes = element.childNodes,
        children = [],
        i = childNodes.length;
    while (i--) {
        if (childNodes[i].nodeType == 1) {
            children.unshift(childNodes[i]);
        }
    }
    return children;
}
var target = document.getElementById('container');
alert(elementChildren(target)[0].children.length);
for (var i = 0; i < elementChildren(target)[0].children.length; i++) {
    elementChildren(target)[0].children[i].style.border = '1px red solid';
    alert(elementChildren(target)[0].children[i].innerHTML);
}
<div id="container" style="padding: 20px; border: 1px dashed grey;"></div>

这是一个代码的代码,所以你可以编辑和玩它:http://codepen.io/nicholasabrams/pen/VLGMgj

最新更新