v0idless
v0idless

Reputation: 948

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

Upvotes: 3

Views: 83

Answers (5)

adeneo
adeneo

Reputation: 318182

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

Upvotes: 3

Derek 朕會功夫
Derek 朕會功夫

Reputation: 94309

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/

Upvotes: 4

goat
goat

Reputation: 31813

$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.

Upvotes: 4

just eric
just eric

Reputation: 927

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.

Upvotes: 0

Pointy
Pointy

Reputation: 413702

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 :-)

Upvotes: 3

Related Questions