Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace element with outerHTML and immediately access the newly created element

I am replacing a DOM element by replacing its content with outerHTML. The trick works, but I need to immediately access the DOM element that was newly created.

Unfortunately the creation of element <x> and generation of the contents of var code is not under my control.

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>

The behavior is explained in MDN's notes on outerHTML:

Also, while the element will be replaced in the document, the variable whose outerHTML property was set will still hold a reference to the original element

So my question is, how can I access the newly added elements immediately after I replaced the old element?

PS: I am ready to abandon outerHTML if there's another way that I can use to replace an element and then access the newly created element.

like image 556
sampathsris Avatar asked Feb 09 '23 12:02

sampathsris


1 Answers

Finally I settled for inserting the new element before, using insertAdjacentHTML, getting the new element by calling previousSibling, and then removing the unnecessary element with 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>
like image 121
sampathsris Avatar answered Feb 12 '23 03:02

sampathsris