1

I have a scenario where I want an event to happen when a button is clicked, but then I want a different behavior when it's clicked the second time. Here's an example of what's happening:

$('.click').not('.clicked').click(function () {
    $(this).addClass('clicked');
    $('<p class="test">Test</p>').insertAfter(this);
});
.clicked {
    color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='button' class="click" value="Click Me" />
<input type='button' class="click clicked" value="Click Me" />
<input type='button' class="click" value="Click Me" />

What I want it to do is stop running the jQuery once the class .clicked is added to the button. This works the way I would expect, if the button already has the class applied, but if I add the class with jQuery it doesn't stop running my function each time the button is clicked.

4
  • 2
    Why not use $('.click').one() instead ...? Commented Jun 9, 2017 at 22:19
  • use $(".click:not(.clicked)") Commented Jun 9, 2017 at 22:20
  • @Liquidchrome I believe this wouldn't work because the event listener would be already bound to the elements when a second click is made. Commented Jun 9, 2017 at 22:24
  • @Circle B Please accept the answer when applicable. Commented Jun 9, 2017 at 22:37

1 Answer 1

4

It does not matter which type of CSS selector you use because it will be executed only once. So you are adding an event listener for every tag with the class .click and without .clicked. You should do something like this:

$(document).on('click', '.click:not(.clicked)', function () {
    $(this).addClass('clicked');
    $('<p class="test">Test</p>').insertAfter(this);
});
.clicked {
    color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='button' class="click" value="Click Me" />
<input type='button' class="click clicked" value="Click Me" />
<input type='button' class="click" value="Click Me" />

Adding the event listener to the whole document and later selecting the tags using .click:not(.clicked) allows you to "evaluate" the css selector every single time.

Sign up to request clarification or add additional context in comments.

3 Comments

Great answer indeed, but why make it so over-cooked? It is completely unnecessary to inject a class when we only need the event handler to work once. The code just becomes difficult to read and harder to maintain. But in a review, it will look much more complicated and badass, I admit that. Job security by code obscurity :)
@davidkonrad I've supposed that this is a minimun and verificable example of a bigger problem. But as you said, only reading the title, it would be much better with one.
@Diego You're the man! The rest of the project (and the reason why I'm wanting to have the clicked class) is that I'm wanting to be able to change styles, behavior and such after clicking. Then I'll remove that class when I click on another one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.