简体   繁体   中英

jQuery set ancestor element for scope

I have a situation where all my selectors all have the same ancestor element

$('#foo .bar')...
$('#foo .some_class')...
$('#foo .some_other_class')...

I was wondering if there was a way to tell jQuery to always assume the selector will descend from #foo ? So something like

$.ancestorWillAlwaysBe('#foo');
$('.bar')...
$('.some_class')...
$('.some_other_class')...
$ancestor = $("#foo");
$$ = function(arg) {
    return $(arg, $ancestor);
}

$$('.bar').html("descendant of foo");

personally I would just use something like $ancestor.find('.bar') though...for code clarity reasons.

Looks like you are lazy to type all those #foo . Here's a way to do that in a simpler way:

var e = $("#foo");  //short enough
$('.bar', e);
$('.some_class', e);
$('.some_other_class', e);

Or if you really that lazy, you can do this:

$ = function(que, anc){
    if($.ancestor){
        return jQuery(que, $.ancestor);
    }else{
        return jQuery(que, anc);
    }
}

$.ancestor = "#foo";  //Ancestor will now always be #foo
$('.bar')...
$('.some_class')...
$('.some_other_class')...
$.ancestor = undefined;  //Clear

DEMO: http://jsfiddle.net/DerekL/agnHy/

There's no simple way to do exactly what you ask, but you can find it:

var $foo = $('#foo');

And then:

var others = $foo.find('.bar');

Remember that when possible it's a good idea to use tag names on the rightmost part of the selector (though nowadays selector interpretation in modern browsers is so fast that optimizations are not often worth the trouble). Thus:

var others = $foo.find('span.bar');

Of course sometimes that's not desirable, if for example you really can't easily narrow down the element types involved.

edit — the convention of giving a cached jQuery result a name starting with "$" is just that: a convention. It's not necessary and I sympathize with those who find it distasteful :-)

I'm a bit lazy and would probably just create a function:

function a(elem) {
    return $('#foo').find(elem);
}

and use it like so:

a('.bar').css('color', 'red');

FIDDLE

Or just create an expression to weed out anything not inside #foo since that is probably what you are after, otherwise just targeting the class would do just fine

$.extend($.expr[":"], {  
    foo: function(elem){  
         return $(elem).closest('#foo').length;  
    }  
}); 

And do:

$('.bar:foo').css('color', 'red');

FIDDLE

I think you are looking for either

Child Selector (“parent > child”)

Which selects all direct child elements specified by "child" of elements specified by "parent"

OR

:first-child Selector

Which selects all elements that are the first child of their parent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM