1

I have the below HTML special content between comments

<p>Regular text</p>
<p>Regular text</p>
<!--Special Content-->
<p>Special Content 1</p>
<p>Special Content 2</p>
<!--/Special Content-->
<p>Regular text</p>
<p>Regular text</p>
<p id="reference">Place special content with comments below this <p> element</p>

I need to wrap the HTML content between the comments <!--Special Content-->and <!--/Special Content--> including the comments themselves into a <div> and move it below the <p id="reference">element.

I have no access to the actual HTML template so it needs to be done via JavaScript or JQuery.

I haven't be able to find a way to wrap the content including the comments so far.

End result should be:

<p>Regular text</p>
<p>Regular text</p>
<p>Regular text</p>
<p>Regular text</p>
<p id="reference">Place special content with comments below this <p> element</p>
<div id="wrapper">
  <!--Special Content-->
  <p>Special Content 1</p>
  <p>Special Content 2</p>
  <!--/Special Content-->
</div>

I appreciate your ideas.

Mike-S122
  • 189
  • 3
  • 14
  • What have you tried so far? I am not so sure if jQuery is the best choice to "locate" comment nodes - that might be simpler in vanilla JS. – CBroe Mar 07 '17 at 17:05
  • @Rory McCrossan: it's for info and tracking. Additional content is dynamically added to the "special content" area and moving it without its comments would create problems for others using the "special content" to reference other actions/events – Mike-S122 Mar 07 '17 at 17:15
  • @CBroe: plain JS is fine too. I appreciate ur orientation. – Mike-S122 Mar 07 '17 at 17:17
  • @Rory McCrossan: the content is pulled from the server and then manipulated in the browser for front-end styling – Mike-S122 Mar 07 '17 at 17:18
  • @RoryMcCrossan What do you mean by "they're not in the DOM"? https://developer.mozilla.org/en-US/docs/Web/API/Comment and https://stackoverflow.com/questions/16151813/is-there-a-dom-api-for-querying-comment-nodes – Lucero Mar 07 '17 at 17:19
  • Well I'd start by going to the parent element, looping through all the child nodes, and checking their nodeType ... (If there can be other comments as well, you might need to check the actual node content as well.) To "move" the nodes to the target element, you can simply use appendChild (that will remove the node from it's original location.) Only thing you have to pay attention to, if you are using any type of "live" collection/NodeList to iterate over the elements, that removing elements will instantly affect the list. – CBroe Mar 07 '17 at 17:30
  • @CBroe: Thank you for the suggestion. I will try that. – Mike-S122 Mar 07 '17 at 17:39

2 Answers2

2

var dataElem = document.getElementById("data");

var doMove = false;
var toMove = [];

for (var i = 0; i < dataElem.childNodes.length; i++) {
  var node = dataElem.childNodes[i];
  if (node.nodeType === Node.COMMENT_NODE && node.data === "Special Content") {
    doMove = true;
  }
  if (doMove) {
    toMove.push(node);
  }
  if (node.nodeType === Node.COMMENT_NODE && node.data === "/Special Content") {
    doMove = false;
  }
}

var targetElem = document.createElement("DIV");
targetElem.setAttribute("id", "wrapper");
dataElem.insertBefore(targetElem, document.getElementById("reference").nextSibling);
for (var i = 0; i < toMove.length; i++) {
  targetElem.appendChild(toMove[i]);
}
<div id="data">
  <p>Regular text</p>
  <p>Regular text</p>
  <!--Special Content-->
  <p>Special Content 1</p>
  <p>Special Content 2</p>
  <!--/Special Content-->
  <p>Regular text</p>
  <p>Regular text</p>
  <p id="reference">Place special content with comments below this <p> element</p>
</div>
Lucero
  • 59,176
  • 9
  • 122
  • 152
0

This will move all the content between your special comment tags after the reference id tag.

let move = false;
let parse = $('body').contents().each(function(k,v){

 if( v.nodeType === 8 ){
  if( v.nodeValue === "Special Content" ) move = true;
  else if( v.nodeValue === "/Special Content") move = false;
 }
 else if(move && v.nodeType === 1)
  $(v).insertAfter('#reference');
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Regular text</p>
<p>Regular text</p>
<!--Special Content-->
<p>Special Content 1</p>
<p>Special Content 2</p>
<!--/Special Content-->
<p>Regular text</p>
<p>Regular text</p>
<p id="reference">Place special content with comments below thiselement</p>
Lucas Shanley
  • 406
  • 2
  • 8
  • 1
    Order of moved nodes is wrong, the comment nodes are not moved as explicitly requested, and they are not put in the wrapper div... ;) – Lucero Mar 07 '17 at 18:08
  • Oh my flavors haha I cant believe I missed that. Looks like you got it handled though. I upvoted your answer :-) – Lucas Shanley Mar 07 '17 at 18:13