jQuery: click event called $('textarea').val().trim().length times

28,636

Solution 1

You may as well just set the button to disabled. This will prevent the click event from firing:

if($('textarea').val().trim().length > 0)
    $('.send-feedback').removeAttr('disabled');
else
    $('.send-feedback').attr('disabled','disabled');

Then separate your click function:

$('textarea').on('input', function(){ ... });
$('.send-feedback').on('click', function() { ... });

JSFiddle example.

thing is, it's not really a button, but an <a>

In that case you can use classes, which I suppose is sort of what you're currently doing:

HTML:

<a href="#" class="send-feedback disabled">Click</a>

JavaScript textarea length check:

if( $(this).val().trim().length > 0 )
    $('.send-feedback').removeClass('disabled');
else
    $('.send-feedback').addClass('disabled');

JavaScript click function:

$('.send-feedback').on('click', function(e) {
    e.preventDefault();
    if($(this).hasClass('disabled'))
        return;

    alert('Clicked!');
});

JSFiddle example.

Solution 2

You are rebinding the click event on every keyup event.

Change the code to check that the button is inactive before binding the click by adding .inactive to the selector:

$('textarea').bind({'keyup' : function(){
    if ($(this).val().trim().length){
        $('.send-feedback.inactive').removeClass('inactive').click(function(){
            console.log('clicked');
        });
    } else {
        $('.send-feedback').addClass('inactive').off('click');
    }
}})

JSFiddle Example

Solution 3

Every time you enter a letter (keyup), you add the event click to .send-feedback.

If you have many .send-feedback, you'll have

(nbr of chars in textarea) * (number of .send-feedback)

times the "clicked" text appear.

You should only add the click event if the .send-feedback has the class "inactive".

Here :

$('textarea').bind({'keyup' : function(){
    if ($(this).val().trim().length) {
        if ($('.send-feedback').hasClass('inactive')){
            $('.send-feedback').removeClass('inactive').click(function(){
                console.log('clicked');
            });
        }
    } else {
        $('.send-feedback').addClass('inactive').off('click');
    }
}})
Share:
28,636
Anton Matyulkov
Author by

Anton Matyulkov

Updated on July 09, 2022

Comments

  • Anton Matyulkov
    Anton Matyulkov almost 2 years

    Well, that's pretty much what happens.

    We've all seen this before: button becomes active and clickable only after we've put something in an input filed. I'm trying to implement that. I guess either I've gone the wrong way and I should've placed my jQuery selectors differently, or it's just something wrong with the code.

    $('textarea').bind({'keyup' : function(){
        if ($(this).val().trim().length){
            $('.send-feedback').removeClass('inactive').click(function(){
                console.log('clicked');
            });
        } else {
            $('.send-feedback').addClass('inactive').off('click');
        }
    }})
    

    Basically, I see 'clicked' in the console multiple times, but if I add console.log('key pressed') before the if check, it's being shown once per keydown, as expected.

    Any advice?