views:

136

answers:

3

Hello, again. :)

God i feel like i'm spamming stackoverflow, this is my 3rd post for today. Sorry, heh.

I even posted a question regarding this before, kind of, but i've changed the code a bit since so i thought it was better to post a new question.

$('.pmlist ul li h4 .toggle').click(function() {
    $(this).closest('.meddel').toggle(250);
});

That's what i've got now. The reason why the closest() method isn't working is because the div .meddel is just next to the h4 element. And closest() only crawls right up the DOM tree, ignoring other child elements. Right? parent() works almost the same and doesn't work either.

And as i only want to toggle the closest .meddel div in the element, i need something that, yeah justs grabs the nearest one, and not all of them.

To clear it up a bit, here's the HTML for one list item:

<li class="item">

<h4><a class="toggle">ämne</a><small>2010-04-17 kl 12:54 by <u>nike1</u></small></h4>

<div class="meddel">
    <span>
        <img style="max-width: 70%; min-height: 70%;" src="profile-images/nike1.jpg" alt="" />
        <a href="account.php?usr=47">nike1</a>
    </span>

    <p>text</p>
</div>

</li>

I have several items like that, and if i click one toggle link, i just want the nearest .meddel to be toggled, as mentioned before.

Thanks. -Nike

+2  A: 

Here's another way to approach this:

$('.pmlist ul li h4 .toggle').click(function() { 
  $(this).closest('h4').siblings('.meddel').toggle(250); 
});

This goes up to the <h4>, then looks for a sibling .meddel element to toggle. You can read more on .siblings() here. This method keeps it a bit more resilient to markup changes, but if the script is tightly coupled anyway, that may not be much of a concern.

Nick Craver
Why are you people answering so fast? I love it! And i love you (in a non-gay kind of way), thanks, it worked :)
Nike
+6  A: 

You could just use:

$(this).parent().next().toggle(250);

Update (according to tvanfosson comment):

$(this).parents(".item").find(".meddel").toggle(250);

This is a much more flexible and safer solution. First it gets the entry container (.item), then find the body of the entry and toggles it. It's less sensitive to feature changes in DOM.

Crozin
Be aware that this is sensitive to the relative DOM placement. That's not necessarily bad, but you will need to update it if you change the DOM so that the parents aren't in this exact sibling relationship. For a less sensitive method, consider going up to the "lowest" common container, then using find based on a class selector as in my answer. This is less sensitive to small changes in the DOM, i.e., it only depends on the "button" and the displayed element being in the same container.
tvanfosson
@tvanfosson: you're completely right. I've changed my answer according to your comment.
Crozin
I noticed that you first used "parent" and then changed to "parents". Are both of them correct? I'm talking specifically about about the spelling now...
Nike
`.parent([selector])` will return the element parent (optionally it will check whether parent match to `selector` if passed), while `.parents([selector])` will return every ancestor. In other words: `parent()` looks only "one-level-up".
Crozin
@Nike - `.parent()` finds the **immediate** parent, *if* it matches the selector (if you passed one, like `.parent(selector)`). `.parents(selector)` finds **all** parents that match, which you shouldn't use in this case, you're better off with `.closest(selector)` since it'll get only the **first/nearest** parent that matches the selector. If further up you had a `class="item"` element, this would all of the sudden have a *very* different effect, toggling children all over, it would actually toggle all `.meddel` *except* the sibling in that case.
Nick Craver
Okey, sounds pretty logical. Thanks!
Nike
+2  A: 

Go up all the way up to the list element, then find the contained element with the matching class. This will be more robust with respect to most minor DOM changes, i.e., it doesn't rely on relative placement.

$('.pmlist ul li h4 .toggle').click(function() {
    $(this).closest('li').find('.meddel').toggle(250);
});
tvanfosson
Thanks a bunch! :)
Nike