Dirty Bird Design
Dirty Bird Design

Reputation: 5553

Cannot exclude element from string

I have a paragraph of text and I need to wrap each group of words (comma separated) in a span tag so I can animate them when hovered on... easy enough. I need to do this to everything except the "a#close". I have tried using the ":not" selector but can't seem to get it to work as desired.

HTML

<div id="stuff"><p>Words Words Words, Words Words Words, Words Words Words, Words Words
Words, Words Words Words, Words Words Words, Words Words Words,
<a href="#" id="close">Close</a></p></div>

jQuery

$(function() {
    $('#stuff:not(a#close)').each(function(){
    var text = $(this).html().split(','),
        len = text.length,
        result = []; 

    for( var i = 0; i < len; i++ ) {
      result[i] = '<span>' + text[i] + '</span>';
    }
    $(this).html(result.join(' '));
});

I can make it work as desired by changing the html mark up and putting the a#close in a p tag with a different ID, but would like to understand the :not selector better, that is if it is the right one to use. thank you

Upvotes: 1

Views: 88

Answers (2)

Josiah Ruddell
Josiah Ruddell

Reputation: 29841

The problem is that the a#close is a child of the container. You could select all nodes and then filter:

$('#stuff *').filter(':not(a#close)').each(function(){
var text = $(this).html().split(','),
        len = text.length,
        result = []; 

    for( var i = 0; i < len; i++ ) {
      result[i] = '<span>' + text[i] + '</span>';
    }
    $(this).html(result.join(' '));
})

You could also use a map function there to avoid the loop:

var result = text.map(function(text){
    return '<span>' + text + '</span>';
});

Upvotes: 1

Cecchi
Cecchi

Reputation: 1535

$('#stuff:not(a#close)') selects all elements with the id stuff, except for those who also match the selector a#close. So really, the :not isn't doing anything in this case. Consider using .contents()

var words = [];
$('#stuff p').contents(':not(a#close)').each(function() {
  words.push($(this).text().split(','));
});​​​​​​​​​​​​​​​​​​
// "words" is now an array of the comma separated strings.

http://jsfiddle.net/s9K7W/

Of course, this is sort of abstracted. In your case you'd modify what is being done in the .each() function to split and wrap the text nodes.

Upvotes: 2

Related Questions