Tarek Mostafa
Tarek Mostafa

Reputation: 398

Using $(this) inside an if statement

I'm trying to make an accordion with 3 panels, so when I click on a panel its content should appear and when I click it again its content should disappear

Here is the jquery code

jQuery(".item").click(function() {

    if ( jQuery(".content").css("display") == "block" )
    {
        jQuery(this).css("display", "none");
    }

    else if ( jQuery(".content").css("display") == "none" )
    {
        jQuery(this).css("display", "block");
    }
}

But the problem here is that jQuery(this) here refers to the class ".item" of course, and the whole panel disappears when clicked.

So I want to refer to ".content" so that only the content of the panel that is being clicked should be displayed or not.

This is the HTML Code:

<div class="container">
    <div calss="row">
        <div class="accordion">

            <div class="item">
                <div class="content"></div>
            </div>

            <div class="item">
                <div class="content"></div>
            </div>

            <div class="item">
                <div class="content"></div>
            </div>

        </div>
    </div>
</div>

I tried this

jQuery(".item").click(function() {

    if ( jQuery(".content").css("display") == "block" )
    {
        jQuery(".content").css("display", "none");
    }

    else if ( jQuery(".content").css("display") == "none" )
    {
        jQuery(".content").css("display", "block");
    }
}

but then when clicked, the contents of all the 3 panels appear/disapear. Any suggestions would be appreciated

Upvotes: 0

Views: 93

Answers (2)

Alnitak
Alnitak

Reputation: 339786

The jQuery constructor can take a second argument that species the element from which to start the search, therefore you'd use:

jQuery('.content', this)

this is semantically identical to (but shorter) than:

jQuery(this).find('.content')

You should consider optimising your code to avoid needless repetition and evaluation of the selector:

jQuery('.item').on('click', function() {
    var content = jQuery('.content', this);
    var display = content.css('display');

    if (display === 'block') {
        display = 'none';
    } else if (display === 'none') {
        display = 'block';
    }
    content.css('display', display);
}

or better yet, just use the built-in jQuery methods for toggling the visibility of elements and get animated transitions (if you should want them) for free:

jQuery('.item').on('click', function() {
    jQuery('.content', this).toggle();
}

Upvotes: 1

MacMac
MacMac

Reputation: 35301

If you pass this in the second argument of jQuery, it will find .content within this. Like so:

jQuery(".item").click(function() {

    if ( jQuery(".content", this).css("display") == "block" )
    {
        jQuery(".content", this).css("display", "none");
    }

    else if ( jQuery(".content", this).css("display") == "none" )
    {
        jQuery(".content", this).css("display", "block");
    }
})

Your click handler is finding ALL of the elements with the selector, so passing this will limit the scope to find the element to hide/show.

To optimize this code, try storing into variables because calling jQuery/$() can be expensive, especially if you need to access the element several times inside the handler. You can use the toggle function to toggle its state from visible to hidden and vice versa.

jQuery(".item").click(function() {

    jQuery(".content", this).toggle();
});

Upvotes: 2

Related Questions