tags:

views:

116

answers:

3
+1  Q: 

jQuery parent()

jQuery snippet:

$(".sliders dt a").click(function(){
    $(this).parent().parent().parent().find(".triggers a").removeClass("active");
    $(this).toggleClass("active");
    $(this).parent().next("dd").slideToggle("fast");
    return false
});

HTML:

<div class="sliders">
    <div class="triggers">
       <a href="#" class="active">Hide all</a>
    </div>
    <dl>
        <dt>
            <a href="#">text</a>
        </dt>
        <dd>text</dd>
    </dl>
</div>

Three .parent() is used, to catch .triggers block. Is there any way to merge them?


jQuery 1.2.6. version is used, thats why .closest() solutions don't work.

+2  A: 

Since .sliders and .triggers are siblings, you need to use .closest() to get .sliders, then traverse over to .triggers, and get its inner a element.

$(".sliders dt a").click(function(){
    $(this).closest('.sliders').prev('.triggers').find("a.active").removeClass("active");
    return false;
});

EDIT:

Question changed, so now answer has changed:

$(".sliders dt a").click(function(){
    $(this).closest('.sliders').find(".triggers a.active").removeClass("active");
    return false;
});
patrick dw
I think this is wrong since, from the jQuery documentation, it finds ancestors, but .triggers is a sibling of .sliders
hunter
@hunter - Well, before the OP code changed, this would actually work since it was using `.closest()` to get the sibling, then using `.prev()` to get `.triggers()`. Moot point now that the question is different.
patrick dw
changed answer doesn't work
Happy
@Happy - Works for me. http://jsfiddle.net/ECvGA/
patrick dw
http://jsfiddle.net/ECvGA/4/ - seens that jQuery 1.2.6. doesn't accept .closest()
Happy
Sorry, I had to write about, thought its not a big difference
Happy
@Happy - Yeah, `closest()` was introduced in version 1.3. jQuery 1.4.2 is definitely worth the upgrade.
patrick dw
@patrick - I have to accept Nick's, solution, he gave the first right answer. Voted for answer and your other two topics up. Thanks.
Happy
@Happy - Understood. Thanks for the votes.
patrick dw
+2  A: 

You can use .closest() like this:

$(".sliders dt a").click(function(){
    $(this).closest(".sliders").find(".triggers a").removeClass("active");
    return false
}); 

This goes up to the .sliders div then back down to find the .triggers a beneath.

Nick Craver
I think this is wrong since, from the jQuery documentation, it finds ancestors, but .triggers is a sibling of .sliders
hunter
@hunter - I'm not using `.triggers` for the selector in `.closest()`, this goes to the whatever that parent is then looks for `.triggers a` beneath.
Nick Craver
I reformatted his code. It is clearer now that the elements in question are siblings. Your solution assumes that the shared parent only has one `.triggers` element.
patrick dw
Html code is now corrected
Happy
@patrick - We think they're siblings...but seeing as it says "Hide All" there may be some repeated elements not included in the question :)
Nick Craver
@Happy - Thanks :) Answer is updated with the correct selector.
Nick Craver
@Nick Craver - Good point as usual. Ultimately we don't have enough code to divine the ultimate intent.
patrick dw
@Nick Craver, .sliders class moved to parent block. DL doesn't have class anymore. Sorry, forget to fix.
Happy
@Happy - The code in this answer will work for the current code in the question, give it a shot.
Nick Craver
I would be happy if it is. Pay attention, I have moved .sliders class to top parent. The structure changed a bit, proposed code doesn't work.
Happy
@Nick Craver - Yeah Nick, pay attention!!! ;o)
patrick dw
@Happy - This code works against the html you posted, you can see for yourself, clicking the `text` link removes the `active` class from `Hide All`: http://jsfiddle.net/v7fs6/
Nick Craver
I know where is the bug - I'm using an old version of jQuery, 1.2.6.
Happy
It has much less size.
Happy
@Happy - When gzipped the difference is *very*, **very** small (and the client should be caching this anyway), you're best upgrading to the latest release, it has many bug fixes and enhancements as well.
Nick Craver
@Nick Craver - thats true. The difference is the first load time. Trying to make a rocket like pages.
Happy
And even you can't know, if a client will use gzip.
Happy
@Nick Craver - the last question, where do you click, to insert nickname for quote, like "@Happy - "? I'm doing it manually
Happy
@Happy - 99.99999% of users will support gzip, this will not impact the load time of your clients. You also have to consider that jQuery has made huge performance increases in 1.3 and 1.4, without upgrading you're missing out of those, probably yielding a **slower** experience for your users.
Nick Craver
@Happy - no click, I type it :)
Nick Craver
God! The next century on the street, where is the click option. Stackoverflow stuck in past :)
Happy
Accepted your answer, thanks.
Happy
@Happy - Welcome :)
Nick Craver
+2  A: 

How does parents() work? It walks up the DOM tree and collects all parents. Than it filters them by the selector specified.

Using jQuery 1.4+ more optimal is to use .closest(). It will work much faster if you have a lot of nodes on your page. Just a thought.

$(this).closest('.sliders').siblings('.triggers').find('a').removeClass(...);

scaryzet
This won't work, `.sliders` is not a sibling of `.triggers` it's a parent :)
Nick Craver