Question

I want multiple elements to change state after clicking on a button. To achieve this I tried to use the jQuery function click() (I tried the .on('click') version as well). For some reason though it runs only the first function and not any of the next ones. I am 100% sure that the solution is completely obvious, but I simply can't come up with anything what would solve it. I used exactly the same method in other projects and it used to work fine, but now I see no differences and yet it still won't just work as expected.

HTML

    <div class="button-open">ASDFG</div>

CSS

    .button-open{
        width:50px;
        height:50px;
        background-color:red;
    }

    .button-close{
        width:50px;
        height:50px;
        background-color:blue;
    }

JS

    $('.button-open').click(function(){

        $(this).removeClass('button-open').addClass('button-close');

    });

    $('.button-close').click(function(){

        $(this).removeClass('button-close').addClass('button-open');

    });

JS Fiddle: http://jsfiddle.net/AbH85/

I'd appreciate any help.

Was it helpful?

Solution

You need to use event delegation.

$(document).on('click', '.button-open', function () {
    $(this).removeClass('button-open').addClass('button-close');
});

$(document).on('click', '.button-close', function () {
    $(this).removeClass('button-close').addClass('button-open');
});

Demo: Fiddle

But it can be simplified as

$(document).on('click', '.button-open, .button-close', function () {
    $(this).toggleClass('button-open button-close');
});

Demo: Fiddle

When you use a normal selector to register an event handler those event handlers are added to the target element, so any changes made to the element attributes after the event registration will not affect the already registered handlers. When using event delegation the selectors are evaluated dynamically.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top