xsist10
xsist10

Reputation: 3051

I'm trying to attach events using on() based on changing selectors

I have a button that can be in 2 different states (lets say Lock and Unlock). When I click on the button, I update the class on the button to reflect the binary opposite state. Each class has a different event attachment function using on(string, callback). For some reason the event being triggered remains the first callback assigned based on the original class.

HTML:

<button class="lock">Lock</button>
<button class="unlock">Unlock</button>

JavaScript:

$(document).ready(function() {
    $('.lock').on('click', function() {

        // Perform some magic here
        console.log('Lock!');

        $(this).removeClass('lock')
               .addClass('unlock')
               .html('Unlock');
    });

    $('.unlock').on('click', function() {

        // Perform some magic here
        console.log('Unlock!');

        $(this).removeClass('unlock')
               .addClass('lock')
               .html('Lock');
    });
});

https://jsfiddle.net/c283uaog/ for testing.

Expected console output when clicking on the same button repeatedly:

Lock!
Unlock!
Lock!

Actual console output:

Lock!
Lock!
Lock!

Any assistance would be greatly desired

Upvotes: 0

Views: 49

Answers (5)

Nikhil Batra
Nikhil Batra

Reputation: 3148

Change your html to this:

<button class="locker lock" >Lock</button>
<button class="locker unlock"">Unlock</button>

<div id="output">Output</div>

and your Js to this:

$(document).ready(function() {
    $('.locker').on('click', function() {
        if($(this).hasClass("lock")){
           $(this).removeClass("lock");
           $(this).addClass("unlock");
           $(this).html("unlock");
         }
          else if($(this).hasClass("unlock")){
           $(this).removeClass("unlock");
           $(this).addClass("lock");
           $(this).html("lock");
         }
    });
});

Upvotes: 0

Navaneeth
Navaneeth

Reputation: 2584

Probably, this question could answer you in a better way: jQuery .on function for future elements, as .live is deprecated
$(document).on(event, selector, handler)

Upvotes: 1

Balachandran
Balachandran

Reputation: 9637

use event Delegation

$(document).on('click','.lock', function() {


 $(document).on('click','.unlock', function() {

updated Demo

Or use in single function with toggleClass

$(document).on('click', '.lock,.unlock', function () {
     $('#output').html($(this).attr('class'));
    $(this).toggleClass('lock unlock').text($(this).attr('class'));

});

ToggleClass demo

Upvotes: 2

stanze
stanze

Reputation: 2480

Use Event Delegation method, Try this updated fiddle,

$(document).ready(function() {
    $(document).on('click', '.lock', function() {
        $('#output').html('Lock!');
        $(this).removeClass('lock')
               .addClass('unlock')
               .html('Unlock');
    });

    $(document).on('click', '.unlock', function() {
        $('#output').html('Unlock!');
        $(this).removeClass('unlock')
               .addClass('lock')
               .html('Lock');
    });
});

Upvotes: 1

Jonas Grumann
Jonas Grumann

Reputation: 10786

I'd do it this way, attaching only one event: http://jsfiddle.net/jozu47tv/

$(".lock").on('click', function(e) {
    e.preventDefault();
    if($(this).hasClass("lock")) {
        $(this).removeClass("lock").addClass("unlock");
        console.log("lock ->  unlock");
    } else {
        $(this).removeClass("unlock").addClass("lock");    
        console.log("unlock -> lock");
    }
})

Upvotes: 1

Related Questions