0

If I insert a comment node into a document fragment, can I convert it to HTML later? Example:

var fragment = document.createDocumentFragment();
var comment = document.createComment('<div>Testing</div>');

fragment.appendChild(comment);

// Convert comment into actual HTML?

What this would look like inside of a fragment:

<!--<div>Testing</div>-->

And how it should be when done (actual DOM):

<div>Testing</div>

Background:

There are many limitations for inserting HTML into a fragment. Fragments don't support innerHTML or insertAdjacentHTML etc. There are other methods for getting HTML into fragments, but they drop certain elements and leave only the inner text. For example, creating a fragment with the createRange API drops those types of nodes and I will be left with a fragment with just the text node "Data"

var fragment = document.createRange().createContextualFragment('<td>Data</td>');

The hope is that if I can convert a comment into actual DOM, that it will work as expected.

KevBot
  • 17,900
  • 5
  • 50
  • 68
  • Is there a reason you need to use a fragment? – Jim Deville Feb 25 '17 at 23:21
  • Yes, I am taking the results of a templating engine (resulting html), adding it to a fragment, attaching events in the fragment, and then appending that fragment to the DOM in one move. This way, I can stay out of the UI for as long as possible. – KevBot Feb 25 '17 at 23:22
  • Please provide a [mcve]. Not really clear what you are trying to do. Comment nodes have nodeType==9. But must be html comment – charlietfl Feb 25 '17 at 23:27
  • Why store it in a comment? Surely the content you are manipulating is the exact opposite of a template? – symcbean Feb 25 '17 at 23:41
  • @symcbean, the HTML comes from a template. As an example, think of the resulting HTML from a handlebars template. The templating engine I am working with returns the resulting HTML. And I am trying to figure out how to get it into a fragment without losing nodes if some of those first childnodes are things like `` or ` – KevBot Feb 25 '17 at 23:44
  • No. Still not clear if what you are describing is a template or variant content, and still not clear why you are defering its parsing, and still not clear why you think a commemt is inany way suitable for delivering the content to the browser. – symcbean Feb 26 '17 at 00:03

5 Answers5

3

For the entire body you can use that snippet:

 var body = document.getElementsByTagName('body')[0],
    bodyHtml = body.innerHTML;
 while (bodyHtml.indexOf("<!--") !== -1) { // will replace all the comments with empty string
    bodyHtml = bodyHtml.replace("<!--", "").replace("-->", ""); 
 }
 body.innerHTML = bodyHtml; 
Hello
<h1>hi</h1>

<!--<div>Testing</div>-->
<!--<div>Testing</div>-->
Cuzi
  • 1,026
  • 10
  • 16
2

Something like this would do the trick

 var element = document.getElementById("whatever"); // get the parent element
 var comment = element.innerHTML; // get the thml
 var html = comment.replace("<!--", "").replace("-->", ""); // remove the comment
 element.innerHTML = html; 
Colm Seale
  • 179
  • 6
2

It sounds like your underlying problem is that you need to stuff HTML text into a DocumentFragment, so here is a helper function to do so for you.

var container = document.createElement('div')

function createFragmentWithHTML (html, doc) {
  var result = (doc || document).createDocumentFragment()
  container.innerHTML = html
  while (container.firstChild) result.appendChild(container.firstChild)
  return result
}


var fragment = createFragmentWithHTML('<div>Testing</div><p><strong>More text</strong></p>')

// do whatever you want with `fragment`
document.body.appendChild(fragment)
gyre
  • 16,369
  • 3
  • 37
  • 47
1

Text content of an HTML comment can be accessed via the nodeValue property of the Node interface or the data property of the CharacterData interface that the HTML Comment interface inherits from:

<!--<div>Example</div>-->
var code = comment.data; /* Now contains `<div>Example</div>` text */
var code = comment.nodeValue; // Same result.

Fwiw, I have a blog post about using HTML comment as data container.

Marat Tanalin
  • 13,927
  • 1
  • 36
  • 52
1

You can get your comments with element.childNodes method, then use textContent method to get the content of comment, then change it into HTML Element with innerHTML method, then remove the comment node and replace it with Element Node.

parseComments('container');

function parseComments(getContainerId){
 var container = document.getElementById(getContainerId);
 var nodes = container.childNodes;
 for(var i=0;i<nodes.length;i++){
  if(nodes[i].nodeType===8){
   var virtualCont = document.createElement('DIV');
   var getContent = nodes[i].textContent;
   virtualCont.innerHTML = getContent;
   container.removeChild(nodes[i]);
   if(nodes[i+1]){
    container.insertBefore(virtualCont.children[0],nodes[i+1]);
   } else {
    container.appendChild(virtualCont.children[0]);
   }
  }
 }
}
<div id="container">
  <h1>some header A</h1>
  <!--<p>some hidden content A</p>-->
  <p>some content</p>
  <!--<p>some hidden content B</p>-->
  <p>another content</p>
  <!--<h1>some hidden header B</h1>-->
  <!--<p>another hidden content C</p>-->
</div>
Paweł
  • 4,238
  • 4
  • 21
  • 40