0

I'm struggling for quite some time with the following question (that looks so simple). I want to change words between double curly brackets without breaking any events.

The difficulty lies in the fact that I don't know what events are set. So the background-color on the span is just an example, but could be anything.

This is my html:

<div class="test">foo <span>bar</span> {{ baz }}</div>

This is my JS:

$("span").
    css('background-color', 'red').
    click(function(){
       alert('Clicked bar!'); 
    });

$( ".test" ).
    contents().
    each(function(){
       if( $(this).text().indexOf('{{') !== -1 )
       {
           $(this).
               text().
               replace(/{{\s?([^}]*)\s?}}/, "HOW DO I CHANGE {{ baz }} FOR SOMETHING ELSE WITHOUT BREAKING THE EVENT? THIS DOESN'T WORK");
       }
    });

Doing something like the example below wouldn't work because it breaks the action on the span.

$('.test').
    html( 
        $('.test').
            html().
            replace(/{{\s?([^}]*)\s?}}/, 'baq')
    );
Bob van Luijt
  • 7,153
  • 12
  • 58
  • 101

2 Answers2

1

To preserve the elements you would want to replace only text inside the elements. You can make a function that loops through the nodes in the element and replaces text in the text nodes, and calls itself with any elements. That way you can replace the text around elements that you want to preserve, and even text inside those elements:

$("span").
    css('background-color', 'red').
    click(function(){
       alert('Clicked bar!'); 
    });

function replace(el) {
  var c = el.childNodes;
  for (var i = 0; i < c.length; i++) {
    if (c[i].nodeType == 3) {
      c[i].textContent = c[i].textContent.replace(/{{\s?([^}]*)\s?}}/, "Something else");
    } else {
      replace(c[i]);
    }
  }
}

replace($('.test')[0]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="test">foo {{ baz }} bar <span>bar {{ baz }} foo</span> foo {{ baz }} foo</div>
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Thanks mate, this is the one – Bob van Luijt Aug 31 '15 at 16:44
  • quick question, if I want to use `textContent` with HTML what would that be? `innerHtml` isn't working :-( – Bob van Luijt Sep 02 '15 at 10:33
  • @bvl: You can't use `textContent` with HTML. A text node only contains text, if you want elements then they don't go inside a text node, they are separate nodes. – Guffa Sep 02 '15 at 10:36
  • aha, that makes sense, but how would that look in your example above with HTML instead of text only? Not sure that I get that 100% – Bob van Luijt Sep 02 '15 at 10:42
  • @bvl: You would use `document.createElement` and `document.createTextNode` for the extra elements and text nodes that you need. If you for example have the text `"foo {{ baz }} bar"` and want to replace `"{{ baz }}"` with an element, you would keep `"foo "` in the text node, create an element and put after the text node, then create a text node with `" bar"` and put after the element. – Guffa Sep 02 '15 at 11:19
0

What you can do is:

<div class="test">foo <span class="bar">bar</span> {{ baz }}</div>

jQuery

$("span").css('background-color', 'red')
$(".test")
    .on("click", "span", function(){
       alert('Clicked bar!'); 
    });

$('.test')
    .html( 
        $('.test')
            .html()
            .replace(/{{\s?([^}]*)\s?}}/, 'baq')
    );

However, you would probably be better off doing a more targeted replace with a specific element for baz, span.baz?

TbWill4321
  • 8,626
  • 3
  • 27
  • 25
  • This makes the assumption that I now the span though. I don't know the clicked elements is a span. – Bob van Luijt Aug 31 '15 at 16:26
  • For bar? You can replace `"span"` with any CSS selector to get the element. You can comma separate possible elements `span, div, img`, or you can select any kind of element `*`. – TbWill4321 Aug 31 '15 at 16:32
  • Thanks, but I mean, I don't know what is happening in the div. Maybe there is an event on the `.test` div, maybe on the span. My point is more that I want to do a replace without breaking the events that I don't know exist. – Bob van Luijt Aug 31 '15 at 16:34