not selector, on() click event

后端 未结 2 1347
孤街浪徒
孤街浪徒 2021-02-20 07:35

I am having some problems in executing the following code:

    var i = 1;  
$(\'.hello:not(.selected)\').on(\'click\',function(){
    $(this).addClass(\'selected         


        
相关标签:
2条回答
  • 2021-02-20 07:38

    The problem is the event handler doesn't get removed just because you change the class. You are attaching the events to the elements, and they stay there forever.

    To get around this, you could just test for the "selected" class on each event handle:

    $('.hello:not(.selected)').on('click',function(){
        if ($(this).hasClass('selected')) {
            $(this).addClass('selected');
            $(this).css({opacity : 0.5});       
            console.log(i++);
        }
    });
    

    But for efficiency and simpler code, you should probably delegate this:

    $('body').on('click', '.hello:not(.selected)', function() {
        var $self = $(this);
        $self.addClass('selected');
        $self.css({opacity : 0.5});       
        console.log(i++);
    });
    

    I used "body" as the element to attach this delegation, but you should probably use something lower in the tree, like a parent or grandparent of the ".hello" elements. This only attaches one event handler, and relies on bubbling to test the selected state of each element as they change in real time.

    Also note that I cached var $self = $(this); that was also for efficiency, so you don't end up jQuery-extending the element more than you need to.

    0 讨论(0)
  • 2021-02-20 07:49

    Your code is taking the set of elements that currently satisfy this criteria:

    $('.hello:not(.selected)')
    

    and setting up this event handler for all eternity:

    .on('click',function(){
        $(this).addClass('selected');
        $(this).css({opacity : 0.5});       
        console.log(i++);   
    });
    

    Particularly important is the fact that once the handler is set on an element, it will continue to be active even if later on that element no longer satisfies the criteria (in this case, by gaining the selected class).

    There are several ways to achieve the desired behavior. One would be to dynamically check that the "filter" condition still holds inside the event handler:

    $('.hello').on('click',function(){
        if($(this).hasClass('selected')) {
            return;
        }
        $(this).addClass('selected');
        $(this).css({opacity : 0.5});       
        console.log(i++);   
    });
    

    Another would be to delegate the event -- in this case, a parent element would be notified of the event on one of its descendants and it would dynamically check that said descendant satisfies the filter condition before deciding to trigger the event handler (code shamelessly pasted from Ben Lee's answer):

    $('body').on('click', '.hello:not(.selected)', function() {
        $(this).addClass('selected');
        $(this).css({opacity : 0.5});       
        console.log(i++);
    });
    
    0 讨论(0)
提交回复
热议问题