This sounds a little crazy, but I'm wondering whether possible to get reference to comment element so that I can dynamically replace it other content with JavaScript.
<html>
<head>
</head>
<body>
<div id="header"></div>
<div id="content"></div>
<!-- sidebar place holder: some id-->
</body>
</html>
In above page, can I get reference to the comment block and replace it with some content in local storage?
I know that I can have a div place holder. Just wondering whether it applies to comment block. Thanks.
This is an old question, but here's my two cents on DOM "placeholders" IMO a comment element is perfect for the job (valid html, not visible, and not misleading in any way). However, traversing the dom looking for comments is not necessary if you build your code the other way around.
I would suggest using the following method:
Mark the places you want to "control" with markup of your choice (e.g a div element with a specific class)
Find the placeholders the usual way (querySelector/classSelector etc)
var placeholders = document.querySelectorAll('placeholder');
var refArray = [];
[...placeholders].forEach(function(placeholder){ var comment = document.createComment('this is a placeholder'); refArray.push( placeholder.parentNode.replaceChild(comment, placeholder) ); });
at this stage your rendered markup should look like this:
replace the second comment with a headline
let headline = document.createElement('h1'); headline.innerText = "I am a headline!"; refArray[1].parentNode.replaceChild(headline,refArray[1]);
If you use jQuery, you can do the following to get all comment nodes
If you only want the comments nodes of the body, use
If you want the comment strings as an array you can then use
map
:Building off of hyperslug's answer, you can make it go faster by using a stack instead of function recursion. As shown in this jsPerf, function recursion is 42% slower on my Chrome 36 on Windows and 71% with IE11 in IE8 compatibility mode. It appears to run about 20% slower in IE11 in edge mode but faster in all other cases tested.
Or as done in TypeScript:
There is an API for document nodes traversal:
Document#createNodeIterator()
:Edit: use a NodeIterator instead of a TreeWalker
It seems there are legitimate (performance) concerns about using comments as placeholders - for one, there's no CSS selector that can match comment nodes, so you won't be able to query them with e.g.
document.querySelectorAll()
, which makes it both complex and slow to locate comment elements.My question then was, is there another element I can place inline, that doesn't have any visible side-effects? I've seen some people using the
<meta>
tag, but I looked into that, and using that in<body>
isn't valid markup.So I settled on the
<script>
tag.Use a custom
type
attribute, so it won't actually get executed as a script, and usedata-
attributes for any initialization data required by the script that's going to initialize your placeholders.For example:
Then simply query those tags - e.g.:
Then replace them as needed - here's a plain DOM example.
Note that
placeholder
in this example isn't any defined "real" thing - you should replace that with e.g.vendor-name
to make sure yourtype
doesn't collide with anything "real".