Link to home
Start Free TrialLog in
Avatar of skij
skijFlag for Canada

asked on

jQuery: Place combined content between matching comments inside special tags

Using jQuery, how can I put the all the content that is between the comments containing "RED" and the comments containing "/RED" inside a set of <em> tags?

All the content between the matching tags should be grouped inside a single set of <em> tags.  The problem with the example below is that many sets of <em> tags are created.

<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<meta charset="utf-8">
<title>Demo</title>
<style type="text/css">em{color:red; border: 1px solid red;}</style>
<script type="text/javascript">
$(function() {
  $("*").contents().each(function(i,e){
    if (e.nodeType===8) {
      if(e.data.indexOf("/RED")>-1) {
        var t = e.previousSibling; 
        while (t.nodeType!==8) {
            if(t.nodeType && (t.nodeType===1 || t.nodeType===3)) {
              $(t).wrap("<em>");
              t = t.parentNode.previousSibling;
            }
            else {
              t = t.previousSibling;
          }
        }
      }
    }

  });
});
</script>
</head>
<body>

 <h1>Lorem <!-- RED --> consectetur <strong>ipsum</strong> <u>eleifend</u> dolor<!-- /RED --> sit amet</h1>
 <div><p>Donec <!-- RED --> <u>consectetur</u> pretium <u>lacus </u> amet<!-- /RED --> lobortis.</p></div>

</body>
</html>

Open in new window

https://jsfiddle.net/6Lhc6w3a/

One idea I had is to appendTo() instead of wrap().  Otherwise, maybe prevUntil() could be used with a filter.  I am open to any other ideas as well, as long as the desire result is accomplished.  Thanks!
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I knew they'd be a simpler way!

(no points, julian's easily answered this one) - if you wanted to retain the comments you would just keep them in the replace:

$(function() {
	var replaced = $('body').html().replace(/\<\!-- RED --\>/g, '<!-- RED --><em>').replace(/\<\!-- \/RED --\>/g,'</em><!-- /RED -->');
	$('body').html(replaced);
});

Open in new window

Avatar of skij

ASKER

What are the implications for dynamic content such as JavaScript and jQuery triggers?  Would they respond to using replace the same was as they would to using things like .prependTo() or .wrap()?
Can you give an example?
Avatar of skij

ASKER

What if jQuery had been used to add an event to some of the content impacted by this?  
For example:
$(document).ready(function() {
    $("a").click(function() {
        //Do stuff when clicked
    });
});

Open in new window

Would using REGEX versus using a different method to manipulate the content have an impact of the way these events were handled?
To make allowances for this do as follows (use the .on method)
$(function() {
    $("body").on('click','a', function() {
        //Do stuff when clicked
    });
});

Open in new window


That will ensure that even dynamically added content will retain its event handlers.
You are welcome.