-1

I'm looking for the equivalent of innerHTML (doesn't reflect changes to the DOM tree after page load) which includes change to the DOM tree after page load. I learned that there're IDL and non-IDL attributes which reflect the initial state on page load and changes respectively.

In case there's no standard Javascript function, I'd accept references to existing library functions as well (it's basically a depth-first iteration over the DOM tree printing element names, all attributes and text content, so I'm sure it exists already).

Question I checked, which don't provide an answer to the question:

Kalle Richter
  • 8,008
  • 26
  • 77
  • 177
  • What is the purpose of grabbing the HTML state? Maybe there is a better solution than what is available. – epascarello Apr 09 '18 at 21:51
  • @epascarello investigating the DOM tree in a headless CI service during functional tests with headless browsers like phantomjs or Chrome. – Kalle Richter Apr 09 '18 at 21:52
  • Seems like that test would be flaws also because I doubt order of attributes and stuff could be trusted. Better off writing tests to check exact things than comparing strings. – epascarello Apr 09 '18 at 21:54
  • @epascarello I'm not using the strings for my test assertions (that'd close to insane), but to get an overview over the page without an image. – Kalle Richter Apr 09 '18 at 21:55

2 Answers2

0

I think your premise is wrong - innerHTML does reflect changes to the DOM after page load, but if you save what it returns in another variable, that new variable won't automatically stay up to date, as seen here:

var innerHTML = document.getElementById("container").innerHTML;
document.getElementById("test").addEventListener("click", function() {
    var newContent = document.createElement("div");
    newContent.innerHTML="HELLO"
    document.getElementById("container").appendChild(newContent);
    console.log({
        current: document.getElementById("container").innerHTML,
        original: innerHTML
    })
});
<div id="container">
    <button id="test">Click me to append a div and log the containers innerHTML</button>
</div>
dave
  • 62,300
  • 5
  • 72
  • 93
  • 1
    And I believe you are wrong in not understanding what OP is asking for. Properties do not update and that is what I think the OP is after. – epascarello Apr 09 '18 at 21:48
  • Thanks for your answer. That'd make my question a duplicate of the second question I referred. – Kalle Richter Apr 09 '18 at 21:53
0

I believe you can get this by just stringifying the document.body.outerHTML.

try this:

 document.body.style.backgroundColor = "red";
 alert(JSON.stringify(document.body.outerHTML));

You should see that the backgroundColor has been set (which means you're seeing the modified dom).

If you're changing an input value, and you want to see it in the dom, you have to set it two ways. First the .value attribute actually sets the value for the field that is read when a form submits. Then you can do a setAttribute("value", "...") to set it visibly in the stringify.

document.getElementById("changeDom").addEventListener("click", function() {
document.getElementById("try").value="xyz"; // sets visible value

document.getElementById("try").setAttribute("value","xyz"); // sets dom value
});
document.getElementById("showDom").addEventListener("click", function() {
alert(JSON.stringify(document.body.outerHTML));
});
<input type="text" id="try"/>
<button id="changeDom">Change</button>
<button id="showDom">Show</button>

If you don't want to set it twice, you can just add an event listener for when the value changes to do the setAttribute for you. JQuery makes this pretty easy. It would look something like this (pseudocode warning):

$(document).on("keypress", "#try", function() { $(this).attr("value",$(this).val()); })'
nixkuroi
  • 2,259
  • 1
  • 19
  • 25