6

Is there any way to attach a click event to several elements, and then have all children to the element, except children of THIS (the one clicked), to run a function?

That's a terrible explanation, but I'm looking for something like this:

$(".block_header").click(function(){
    $(".block_header span:not(this span)").toggleClass("collapse expand");
    $(".container:not(this+div.container)").slideToggle();
});

Here's a sample HTML:

<h3 id="sender_header" class="block_header"><span>Sender</span></h3>
<div id="sender_container" class="container">
    <p>Show or hide this, based on which H3 is clicked.</p>
</div>
<h3 id="receiver_header" class="block_header"><span>Receiver</span></h3>
<div id="receiver_container" class="container">
    <p>Show or hide this, based on which H3 is clicked.</p>
</div>
<h3 id="delivery_header" class="block_header"><span>Delivery</span></h3>
<div id="delivery_container" class="container">
    <p>Show or hide this, based on which H3 is clicked.</p>
</div>
<h3 id="items_header" class="block_header"><span>Items</span></h3>
<div id="items_container" class="container">
    <p>Show or hide this, based on which H3 is clicked.</p>
</div>
.... etc, etc (many more of the same)

Hope this isn't too complicated. It would save me a LOT of code.

Richard Harris
  • 929
  • 3
  • 8
  • 14

4 Answers4

15

Rather than excluding the element in the selector, you can use the not() function, which accepts a DOM element or jQuery object to remove from the jQuery set.

$(".block_header").click(function(e) {
    $('.block_header span').not($(this).find('span')).toggleClass("collapse expand");

    $('.container').not($(this).next()).slideToggle();
});
Matt
  • 74,352
  • 26
  • 153
  • 180
3

Try this:

$(this).parent('h3').siblings('h3').children('span').addClass('active');
$(this).parent('h3').siblings('h3').next('div.container').slideToggle('active');

That should do the trick!

However, can I assume that you will only ever have one active?

If that is the case, this is the easiest:

$('.active').removeClass('active').parent('h3').next('div.container').slideUp();

Hope that helps :)

edit:

To be extra clever, store the active one as a variable. So on click:

$active = $(this);

Then, next time you can do this, without getting jQuery to go finding the element again:

$active.removeClass('active').parent('h3').next('div.container').slideUp();
$active = $(this);
will
  • 4,557
  • 6
  • 32
  • 33
  • Holy cow you guys are brilliant! So many useful answers. Thanks so much! Oh, and yes: only one will ever be active at a time. – Richard Harris May 15 '12 at 10:56
  • I want to vote yours up but I need 15 reputation and all I have is 11. Sorry. If I could mark two solutions as "solved" I would pick yours as well for so many great tips. Cheers! – Richard Harris May 15 '12 at 11:08
2
$(".block_header").click(function(){
    $(".block_header span").not($('span', this)).toggleClass("active");
    $(".container").not($(this).next()).slideToggle();
});
The System Restart
  • 2,873
  • 19
  • 28
1

Do it like

 $(".block_header").not(this).find("span").toggleClass("collapse","expand");

 $(".container").not(this).not("div.container").slideToggle();
Imdad
  • 5,942
  • 4
  • 33
  • 53