Bob van Luijt
Bob van Luijt

Reputation: 7598

How to replace text using jQuery (or plain JS) without breaking any events?

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')
    );

Upvotes: 0

Views: 221

Answers (2)

Guffa
Guffa

Reputation: 700910

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>

Upvotes: 1

TbWill4321
TbWill4321

Reputation: 8676

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?

Upvotes: 0

Related Questions