Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exclude child elements from functions with jquery

With the code below:

<p>Red red red red <a href="http://www.google.com"> this should be red alone</a> red red</p>

How would I change all 'red's to 'yellow's EXCEPT the one in the 'a' tag?

I've got this far:

$("p").html(function(i,event){
    return event.replace(/(red)/g,'yellow');
});

...which changes everything to yellow. I assume I need to add in an if clause saying something along the lines of:

if (event.target.tagName === "a")
{return false}

But I've tried dozens of things I've found on stackoverflow, to no effect. Any ideas?

like image 840
JohnG Avatar asked Feb 16 '17 14:02

JohnG


2 Answers

You can iterate the text nodes using contents(). This will not have any impact on any event listeners on the inner elements the way using html() would

$('p').contents().each(function() {
  if (this.nodeType === 3) {
    this.textContent = this.textContent.replace(/red/gi, function(match) {
      return match === 'Red' ? 'Yellow' : 'yellow'
    });
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Red red red red <a href="http://www.google.com">red</a> red red</p>
like image 165
charlietfl Avatar answered Nov 02 '22 06:11

charlietfl


Dirty way because too specific and won't work if many <a> in <p> for instance, but works if in <p> there is only one <a>.

The best way is to figure out the right regex.

var aContent = $('p > a')[0].outerHTML;

$('p').html(function(i,event) {
    var parts  = event.split(aContent);

    for (var i, l = parts.length; i<l; i++) {
        parts[i] = parts[i].replace(/red/ig, 'yellow');
    }

    return parts.join(aContent);
});
<p>Red red red red <a href="http://www.google.com">red</a> red red</p>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
like image 1
smarber Avatar answered Nov 02 '22 07:11

smarber