That approach won't work because of the HTML comment in the block. If the comments weren't there, your code wouldn't be far off, but:
- It's
innerHTML
, not htmlInner
- You have to assign the result of
replace
, it doesn't modify the string you call it on (more in this question's answers)
But that approach also has the problem that if you have any event handlers on anything in that pre
element, they'll get removed by assigning to innerHTML
.
But we need to handle the comment nodes, which means it's a tiny bit more complicated; see comments:
// Start with the first child of the `pre`
let node = document.querySelector("#main pre").firstChild;
// Stop when we run out of nodes or find the first element node
while (node && node.nodeType !== Node.ELEMENT_NODE) {
const next = node.nextSibling;
if (node.nodeType === Node.TEXT_NODE) {
// Text node, remove leading whitespace
node.nodeValue = node.nodeValue.trimStart();
if (node.nodeValue) {
// Non-empty text node after trimming; stop
break;
} else {
// Empty text node, remove
node.remove();
}
}
node = next;
}
Live Example:
// Start with the first child of the `pre`
let node = document.querySelector("#main pre").firstChild;
// Stop when we run out of nodes or find the first element node
while (node && node.nodeType !== Node.ELEMENT_NODE) {
const next = node.nextSibling;
if (node.nodeType === Node.TEXT_NODE) {
// Text node, remove leading whitespace
node.nodeValue = node.nodeValue.trimStart();
if (node.nodeValue) {
// Non-empty text node after trimming; stop
break;
} else {
// Empty text node, remove
node.remove();
}
}
node = next;
}
<div id="docmap"></div>
<div id="main"><pre>
<!----------------------------------------------->
<!-- do not edit above
<!----------------------------------------------->
<h1>Jabberwocky 1</h1>
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe:
All mimsy were the borogoves,
And the mome raths outgrabe.
</pre>
</div>
That code assumes a modern browser, it won't work on IE11. If you need to support IE11, we have to remove any ES2015+ stuff (let
, const
, trimStart
) and use removeChild
rather than the newer remove
:
// Start with the first child of the `pre`
var node = document.querySelector("#main pre").firstChild;
// Stop when we run out of nodes or find the first element node
while (node && node.nodeType !== Node.ELEMENT_NODE) {
var next = node.nextSibling;
if (node.nodeType === Node.TEXT_NODE) {
// Text node, remove leading whitespace
node.nodeValue = node.nodeValue.replace(/^\s+/g, ""); // No need for the `g` flag
if (node.nodeValue) {
// Non-empty text node after trimming; stop
break;
} else {
// Empty text node, remove
node.parentNode.removeChild(node);
}
}
node = next;
}
Live Example:
// Start with the first child of the `pre`
var node = document.querySelector("#main pre").firstChild;
// Stop when we run out of nodes or find the first element node
while (node && node.nodeType !== Node.ELEMENT_NODE) {
var next = node.nextSibling;
if (node.nodeType === Node.TEXT_NODE) {
// Text node, remove leading whitespace
node.nodeValue = node.nodeValue.replace(/^\s+/g, ""); // No need for the `g` flag
if (node.nodeValue) {
// Non-empty text node after trimming; stop
break;
} else {
// Empty text node, remove
node.parentNode.removeChild(node);
}
}
node = next;
}
<div id="docmap"></div>
<div id="main"><pre>
<!----------------------------------------------->
<!-- do not edit above
<!----------------------------------------------->
<h1>Jabberwocky 1</h1>
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe:
All mimsy were the borogoves,
And the mome raths outgrabe.
</pre>
</div>
That works all the way back to IE9. (It would work in IE8 if you replaced Node.ELEMENT_NODE
with 1
and Node.TEXT_NODE
with 3
.)