1

I have h3 block's and on click of each of the block I am showing the section associated with it. It is actually something like accordion(hide and collapse). I have also given a drop icon to the h3 tags, means that when the block is opened the h3 should have a dropicon pointing downwards while others h3 should have there dropocons towards right. I am controlling this behaviour using backgroundPosition. I am using the jQuery visible condition to see if the particular block is visible then give its drop icon one background position and to the rest other. It works fine but only for first click. It doesn't work for second click; can somebody explain why? Here is my code:

if($(this).next().is(':visible')) {
    $(this).css({'backgroundPosition':'0px 14px'});
}
else {
    $("h3").css({'backgroundPosition':'0px -11px'});
}

UPDATED CODE:

$("h3").click(function() {          
    $(".tabs").hide();
    $(this).next().show();

    if($(this).next().is(':visible')) {
        $(this).css({'backgroundPosition':'0px 14px'});
    } else {
        $("h3").css({'backgroundPosition':'0px -11px'});
    }
})
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Mike
  • 3,348
  • 11
  • 45
  • 80

6 Answers6

2

If you wrap the whole block in a div it might make traversing easier.

Html:

<div class="drop-block">
<h3>Click this</h3>
    <ul>
        <li>Drop</li>
        <li>it</li>
        <li>like</li>
        <li>it's</li>
        <li>hot</li>
   </ul>
</div>​

Jquery:

var dropper = $('.drop-block'); 
$(dropper).find('h3').click(function(){ 
    $(this).toggleClass('active');
    $(dropper).find('ul').toggle();
});​

Example

Jeanette
  • 21
  • 3
1

I Belive that you are looking for live

So it will be something like this:

$(element).live('click', function(){
    if($(this).next().is(':visible')) {
        $(this).css({'backgroundPosition':'0px 14px'});
    }
    else {
        $("h3").css({'backgroundPosition':'0px -11px'});
    }
}
Michel Ayres
  • 5,891
  • 10
  • 63
  • 97
  • jQuery `.live()` is useful if you are dynamically adding/removing event driving HTML. Ie. If you have a list of H3 and you just use `.click()`, only the H3 items currently in the document will get the event function attached to it. If you dynamically add more H3 later on, they will not have the event code associated with them. If you use `.live()`, jQuery will attach the event handler each time something is dynamically added. I would use `.click()` unless you need dynamic usage. I would expect extra cost to use `.live()`. – jmbertucci Apr 02 '12 at 19:52
  • [Here](http://stackoverflow.com/questions/1368223/performance-difference-between-jquerys-liveclick-fn-and-clickfn) is a great link that talk about click and live('click'). Take a look. – Michel Ayres Apr 02 '12 at 20:42
0

Instead of editing the css of them, make a css class "open" (or similar), and then add / remove the class on the click to open / close.

It is much easier to debug by checking for the existence of a class than it is to check the css properties of something in JS.

Kristian
  • 21,204
  • 19
  • 101
  • 176
0

Better make a class name for each situation and easly handle the action

$('h3').on('click', function(){
   if($(this).hasClass('opened')) {
     $(this).removeClass('opened');
   }
   else {
      $(this).addClass('opened');
    }
}
safarov
  • 7,793
  • 2
  • 36
  • 52
0

It sounds like you need to bind click events to the h3 elements and toggle the visibility of the child elements:

$(function(){
    $("h3").click(function(){
        $(this).next(".tabs").toggle();
    });
});

Example markup:

<h3>Item 1</h3>
<div class="tabs">
    <h4>Option 1</h4>
    <h4>Option 2</h4>
</div>
<h3>Item 2</h3>
<div class="tabs">
    <h4>Option 1</h4>
    <h4>Option 2</h4>
</div>

Here's a jsFiddle to demonstrate.

James Johnson
  • 45,496
  • 8
  • 73
  • 110
  • makes no difference, I think the DOM traversal is not happening properly, for h3 tags – Mike Apr 02 '12 at 19:29
  • 1
    Can you post some of your markup so we can see how you're building the accordion? – James Johnson Apr 02 '12 at 19:35
  • Exactly the same way as you suggested above. The only difference is you have ul li, and I have div with class = "tabs" – Mike Apr 02 '12 at 19:39
  • I updated my example, and included a jsFiddle to show you that it works. If it's not working for you, there's probably an issue somewhere else in your markup. – James Johnson Apr 02 '12 at 20:16
0
$(document).on('click', 'h3', function(e) {          
    $(".tabs").hide('slow'); 
    $(this).css({'backgroundPosition':'0px 14px'});

    if(!$(this).next().is(':visible'))
    {
        $("h3").css({'backgroundPosition':'0px -11px'});
        $(this).next().show('slow');
    }
});

You can remove 'slow' from show/hide if animation is not required

Here is an example.

The Alpha
  • 143,660
  • 29
  • 287
  • 307