0

there has a div and tow click events

HTML:

<div class="noSel"></div>

JS:

$('.noSel').on('click', function(){
    alert('noSel');
    $(this).removeClass('noSel').addClass('sel');
});

$('.sel').on('click', function(){
    alert('sel');
    $(this).removeClass('sel').addClass('noSel');
});

first time click should alert "noSel"

second time click should alert "sel"

but always alert "noSel"

HTML:

<div id="div" class="noSel"></div>

JS:

$('#div').on('click', function(){
    if($(this).hasClass('sel')){
        alert('sel');
        $(this).removeClass('sel').addClass('noSel');
    }else{
        alert('noSel');
        $(this).removeClass('noSel').addClass('sel');
    }
});

This way is OK, but have other way to do this?

Alex M
  • 2,756
  • 7
  • 29
  • 35
王策士
  • 1
  • 1

2 Answers2

4

You have to use live delegation for dynamic listeners. Otherwise you have to rebind it manually, using .on() and .off(). jQuery will register normal listeners only once, not on change of maybe classes.

$(document).on('click', '.noSel', function() {
    alert('noSel');
    $(this).removeClass('noSel').addClass('sel');
});

$(document).on('click', '.sel', function(){
    alert('sel');
    $(this).removeClass('sel').addClass('noSel');
});

The long version (manually way) could be look something like this:

function sel() {
    alert('sel');
}

function noSel() {
    alert('noSel');
}

$('.noSel').on('click', function() {
    noSel();

    // you will not need to change classes, but you can
    // $(this).removeClass('noSel').addClass('sel');

    $(this).off('click').on('click', sel);
});

$('.sel').on('click', function() {
    sel();

    // you will not need to change classes, but you can
    // $(this).removeClass('sel').addClass('noSel'):

    $(this).off('click').on('click', noSel);
});
eisbehr
  • 12,243
  • 7
  • 38
  • 63
0

The reason is that when you bind the listeners jQuery will find all elements which conform to the specific selector, and bind listeners on them. Even if you change the element to no longer conform to that selector, the same event listener will be called.

I think your own suggestion is fine.

peternyc
  • 581
  • 3
  • 8