markzzz
markzzz

Reputation: 47945

Handler doesnt get an event

I have this code : if you try to click on Button 2 or 3 you can see the right effect. Now, go back and try to click on Button 1 : nothing happens.

Why? Thanks

$('.navigatorUserButtonOff').click(function(e){
    e.preventDefault();
    $('.navigatorUserButtons').find('.navigatorUserButtonOn').removeClass().addClass('navigatorUserButtonOff');
    $(this).removeClass().addClass('navigatorUserButtonOn');
});

Upvotes: 4

Views: 111

Answers (9)

Robert Koritnik
Robert Koritnik

Reputation: 105029

The reason why it's not working

Because this selector you use at the beginning to bind click handler

$('.navigatorUserButtonOff')

selects only the second and third button. So you're binding click handler only them couple. First button doesn't have this class hence no click handler is bound to it.

Two posible solutions

  1. use delegate (you could use live as well but using delegate is better and works faster)

    $(".navigatorUserButtons").delegate(".navigatorUserButtonOff", "click", function(evt){
        evt.preventDefault();
        // remove and add classes as desired
    });
    

    This one will be a bit problematic because click handler will only be working on the off state buttons which means that clicking on the on state button will execute default browser behaviour that happens when you click a link. This is definitely not desired in your situation and you'll have to bind a click event to a on button as well to prevent default behaviour.

  2. A much better approach is to use a separate class that defines a button and a different one for its on/off state:

    <a class="navigatorUserButton on">...</a>
    

    And you don't need off state at all neither delegated events:

    $(".navigatorUserButton").click(function(evt){
        evt.preventDefault();
        var $this = $(this);
        if (!$this.hasClass("on"))
        {
            $this.siblings(".on").removeClass("on");
            $this.addClass("on");
        }
    });
    

Upvotes: 3

Amir Raminfar
Amir Raminfar

Reputation: 34169

That's easy one. It because you did

$('.navigatorUserButtonOff').click(...)

Which only does on click for navigatorUserButtonOff. Change it to

$('.navigatorUserButtons a').click(...)

Upvotes: 2

Brian Driscoll
Brian Driscoll

Reputation: 19635

It's not working because the selector is filtering for elements that already have a class set to navigatorUserButtonOff, which your first button doesn't have when the document is loaded.

Upvotes: 2

Madcowe
Madcowe

Reputation: 243

from what I've tested, if I changed the <div class="navigatorUserButtons"> <a id="view_tracklist" class="navigatorUserButtonOn" href="#">Button 1</a> and instead of navigatorUserButtonOn, you put Off, then it becomes clickable, and highlights just as the others do

Upvotes: 2

Hrant Khachatrian
Hrant Khachatrian

Reputation: 3109

Because when you are attaching the event to $('.navigatorUserButtonOff') elements, the first button is not within them! So it doesn't get the event handler. Try this:

$('.navigatorUserButtons a').click(function(e){
    e.preventDefault();
    if($(this).hasClass('navigatorUserButtonOn'))
        return false;
    $('.navigatorUserButtons').find('.navigatorUserButtonOn').removeClass().addClass('navigatorUserButtonOff');
    $(this).removeClass().addClass('navigatorUserButtonOn');
});

Upvotes: 1

amit_g
amit_g

Reputation: 31250

Because the click event is not attached to first button. It is attached to only items that have class navigatorUserButtonOff. The first one has class of navigatorUserButtonOn. You could use the live instead

$('.navigatorUserButtonOff').live("click", function(e){
    e.preventDefault();
    $('.navigatorUserButtons').find('.navigatorUserButtonOn').removeClass().addClass('navigatorUserButtonOff');
    $(this).removeClass().addClass('navigatorUserButtonOn');
});

Demo.

Upvotes: 2

Alvaro Ardila
Alvaro Ardila

Reputation: 372

That's because you are adding an event to all navigatorUserButtonOff and right after you did that you change the navigatorUserButtonOn to navigatorUserButtonOff so you have to add the event to the first button right after you change it

Upvotes: 1

JaredPar
JaredPar

Reputation: 754763

The reason this occurs is because the code which hooks up the events only runs once. At the time it runs button 2 and 3 meet the criteria and succesfully hookup the event. Later changes to the DOM qualify button 1 for the filter but it doesn't run again and hence button #1 doesn't get hooked up.

You can fix this by using the live function in jQuery.

$('.navigatorUserButtonOff').live('click', function(e){
  e.preventDefault();

  $('.navigatorUserButtons').find('.navigatorUserButtonOn').removeClass().addClass('navigatorUserButtonOff');
  $(this).removeClass().addClass('navigatorUserButtonOn');
});

Here is a link to a working version

Upvotes: 2

Gabriel
Gabriel

Reputation: 1833

When the code is run, it finds all the off buttons (2 and 3, because initially 1 is on) and adds that event listener to its click event. You have to do that for all the div's children, because that function assignment is only executed one time.

Upvotes: 1

Related Questions