Howard
Howard

Reputation: 19805

jQuery filter and html return strange result

Why the following code not work as expected? (Select all elements before the div with class = clear?)

HTML:

<div id="text">    
    line0
    <div>line1</div>
    <div>line2</div>

    <div class="clear" />        
    <div>dummy</div>
    <p>dummy</p>        
</div>

JS:

var allow = true;    
var output = $('#text *').filter(function(index) {        
    if( $(this).attr("class") == 'clear') {
        allow = false;
    }

    return allow;        
}).html().trim();

alert( output );

​Output:

line1

Expect: line0 line1 line2

Upvotes: 1

Views: 85

Answers (3)

Prasenjit Kumar Nag
Prasenjit Kumar Nag

Reputation: 13461

This happens because as the .html() says

Get the HTML contents of the first element in the set of matched elements.

So though both of your div is selected only one is returned by .html()

Check this fiddle to verify you code is returning both elements.

And as other have already said you should use the .hasClass method.

UPDATE

As that line0 is not inside any node, its a textNode, You can loop and add span tags around textNodes first. Or you wont be able to apply styling to that text. Check the following code

var whitespace = /^\s*$/;
$('#text').contents().filter(function(){
    return this.nodeType == 3 && !whitespace.test(this.nodeValue);
}).wrap('<span></span>');

This loops through all childNodes(including textnodes) and wrap non-space textnodes with span.

So after that your line0 will be inside a span tag like <span>line0</span>. So now if you do

$('.clear').prevAll().css('color', 'red');

It will highlight line0 too.

Check Node Types Doc on MDN

Working Fiddle

Upvotes: 3

OlliM
OlliM

Reputation: 7113

Because the html() method returns the contents of the first element in the selector.

http://api.jquery.com/html/

If the selector expression matches more than one element, only the first match will have its HTML content returned.

Upvotes: 2

gdoron
gdoron

Reputation: 150253

$('.clear').prevAll().css('color', 'red').fadeOut(2000);​

Live DEMO

And by the way, if you want to check if an element has a class use .hasClass(class)
Example:

var hasClass = $(this).hasClass('clear');

Upvotes: 1

Related Questions