Changing button classes dynamically not working - javascript

<button class="changeMe"> Click Me </button>
$(".changeMe").on("click", function(){
console.log("I should only work the first time!")
$("changeMe").addClass("secondClass").removeClass("changeMe");
});
$(".secondClass").on("click", function(){
console.log("Now I should Work!")
});
This is basically what my code looks like.
I click the button.
Chrome developer tools show that the class was removed.
I click the button again, and the same bit of jquery code runs even thou the class its pointing too dosnt exist.
How do I stop that from happening.
EDIT:: Ooopss forgot the dot. I have the dot in my solution. This is just for demonstration purposes. Added dot.

1) Add . before class name, so it will be $(".changeMe") and $(".secondClass")
2) Use $(document).on("click") event
Try:
$(document).on("click",".changeMe", function(){
console.log("I should only work the first time!")
$(".changeMe").addClass("secondClass")
$(".changeMe").removeClass("changeMe");
});
$(document).on("click",".secondClass", function(){
console.log("Now I should Work!")
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<button class="changeMe"> Click Me </button>

Try this on clicking .secondClass. You have to bind the events dynamically.
$(document).on("click",".secondClass", function(){
console.log("Now I should Work!")
});

You need to use event delegation because you are changing classes manually. Also . is needed for selecting class names.
Edit : Instead of event delegation, you can use the following, bind the event to the second class, after the class is added.
Use one() for binding to work only once.
$(".changeMe").one("click", function(e){
console.log("I should only work the first time!")
$(".changeMe").addClass("secondClass").removeClass("changeMe");
$(".secondClass").on("click", function(){
console.log("Now I should Work!")
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="changeMe"> Click Me </button>

This code should work
$("body").on("click", '.changeMe', function(){
console.log("I should only work the first time!")
$(".changeMe").addClass("secondClass").removeClass("changeMe");
});
$("body").on("click", '.secondClass', function(){
console.log("Now I should Work!")
});

Try the following:
$(".changeMe").on("click", function(e){
if($(e.target).is('.changeMe')) {
console.log("I should only work the first time!")
$(".changeMe").removeClass("changeMe").addClass("secondClass");
} else {
console.log("Now I should Work!");
}
});

Related

Jquery appended buttons on click with classes

I have a problem I noticed many times but still haven't understood the real reason.
I have a script that append some .btn buttons by clicking the button #add.
Of course the .btn buttons are to be clicked. So I made an event after the append():
$(".btn").on('click', function(){
alert('clicked');
});
This function works as I want. When I create a button and click on it, it will alert me. But the problem comes when I create more than one button and that I click on one of them. It will pop up an alert for the button I clicked, and for each button with the class that comes after it in the source code.
(As an example, if I create 3 buttons, if I click the first it will alert three times. If I click the second it will alert two times, and if I click the last, it will alert one time.)
I assume that it must be about some Javascript notions I haven't well understood yet. Probably a problem with the class ? I'm a bit lost.
Here is an example if you want to see by yourself : https://jsfiddle.net/nmza0ae4/
Thank you in advance !
Try this : when you add click handler to button user $(".btn").on('click'.. it will add to only available buttons at that point of time.
To add click handler to dynamically added buttons, use below code
$(document).on('click',".btn", function(){
alert('clicked');
});
$('#add').click(function(){
$('html').append('<button class="btn">Test</button>');
$(".btn").on('click', function(){
alert('clicked');
});
});
What you are doing is adding event handler on each click. When new button is added, new event handler is attached to button and hence multiple alert.Put event handler outside the scope
$('#add').click(function(){
$('html').append('<button class="btn">Test</button>');
});
$(document).on('click',".btn", function(){
alert('clicked');
});
You can use $(document).on('click' function ...
$(document).ready(function(){
$('#add').click(function(){
$('html').append('<button class="btn">Test</button>');
});
});
$(document).on('click',".btn", function(){
alert('clicked');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="add">
Add
</button>
As the Add button adds to dom you will need event delegation. Code for adding the button tag looks fine.
$(document).ready(function(){
$('#add').click(function(){
$('html').append('<button class="btn">Test</button>');
});
});
$(document).on("click",'.btn', function(){
alert('clicked');
});
You can unbind the event before binding the event like this.
$('#add').click(function(){
$('html').append('<button class="btn">Test</button>');
$(".btn").off("click");
$(".btn").on("click",function(){
alert('clicked');
})
});
or you can globally write the click event for all the dynamically added button like
$('#add').click(function(){
$('html').append('<button class="btn">Test</button>');
});
$(document).on('click',".btn",function(){
alert('clicked');
});
But the standard way is the 2nd one.
https://jsfiddle.net/Rishi0405/nmza0ae4/2/
try this:
$(document).ready(function(){
$('#add').click(function(){
$('html').append('<button class="btn">Test</button>');
});
$(document).on('click',".btn", function(){
alert('clicked');
});
});

jQuery .click() only working once

I am trying to make some text that changes when you click it, but changes back if you click it again.
It works fine, once. But if i try it a second time, nothing happens.
My HTML:
<div id="text">
<p>TEXT1</p>
</div>
JavaScript/jQuery:
$(document).ready(function(){
$("#text").click(function(){
$(this).html("<p>TEXT2</p>").click(function(){
$(this).html("<p>TEXT1</p>");
});
return false;
});
});
Example:
http://mrkireko.github.io/jQueryExample/
I'd suggest instead:
$('#text p').click(function(){
$(this).text(function(i,t){
return $.trim(t) === 'text1' ? 'text2' : 'text1';
});
});
JS Fiddle demo.
References:
click().
jQuery.trim().
text().
It's because after the first click, you now have two handlers assigned,
The first one still puts the TEXT2 in place, but the second one changes it back.
One correct solution is to use the handler version of .toggle():
$(document).ready(function(){
$("#text").toggle(function(){
$(this).html("<p>TEXT2</p>");
return false;
}, function(){
$(this).html("<p>TEXT1</p>");
return false;
});
});
As #KevinB noted, this version of .toggle() is deprecated. To do your own toggle, you can do this:
$(document).ready(function() {
$("#text").click(function(i){
return function() {
$(this).html(++i % 2 ? "<p>TEXT2</p>" : "<p>TEXT1</p>");
return false;
};
}(0));
});
DEMO: http://jsfiddle.net/NkGZj/
You are binding multiple click handlers to the same element, and they are all executing every time you click. Since the handler to change the text to TEXT1 executes last, that's what you end up with.
See the console.log() output here:
http://jsfiddle.net/tcMx5/
Binding event handlers in event handlers is almost never the right thing to do. Instead, have one handler that checks the current state and toggles the value.
Several answers here, some will work well. Here is another option, using class:
<div id="text" class="state1">
<p>TEXT1</p>
</div>
$(document).ready(function(){
$("#text").click(function(){
var $this = $(this);
if ($this.hasClass('state1')) {
$this.html('<p>TEXT2</p>');
}
else {
$this.html('<p>TEXT1</p>');
}
$this.toggleClass('state1');
});
});
I would lean more towards this solution because it is not dependent on what is actually contained within the element. Unless, of course, you know that it will never change and you can reliably target the string.
You can do something like this:
$( "#text" ).toggle(function() {
this.html("<p>text 2</p>");
}, function() {
this.html("<p>text 1</p>");
});

jQuery selector click function clarification

Theres a gap in my understanding that i'd liked filled;
I have a basic jQuery click function like this..
$('.cl').each(function(e)
{
alert('works');
$(this).click(function()
{
alert('no works');
});
});
My HTML is like this:
<body>
<div id='c0'>
<div class='bO cl'>Button</div>
</div>
</body>
Basic stuff.
The 'works' alert is fired ok - but with the click function nothing happens - 'no works' is not fired.
Also
$('.cl').click(function()
{
alert('help');
});
Does not work. Simple stuff i'm sure but i'm missing something.
Why is this?
One thing to make sure is that you run the event handler once the DOM and jQuery are initialized, which is by doing this:
$(function() {
$('.cl').click(function()
{
alert('help');
});
});
Also alternatively, if your cl is loaded after the fact such as by an Ajax call you can alternativley do this
$("body").on("click", ".cl", function() {
// Your code here
})
This registers the click event with the body but only gets dispatched if the actual target is of type cl.

click event on input button

I try to bind a function to the click event on input button, but it doesn't seems to work and method is not called:
<div id='back'>
<input type="button"/>
</div>
jQuery:
$('#back').click(clickOnBackbutton);
function clickOnBackbutton(){
console.log('back to menu'); //function not called
}
I do not prefer to use onClick event, instead i prefer to use that approach. Thanx in advance.
You should put your code within document ready handler. also note that you are selecting the div tag instead of the input element.
$(document).ready(function(){
$('#back input[type=button]').click(clickOnBackbutton);
// $('#back input[type=button]').click(function(){
// or do something here
// });
})
Button:
<div id='back'>
<input type="button" id='back-button'/>
</div>
jQuery:
$(document).ready(function(){
$('#back-button').click(function(){
console.log('Back to Menu');
});
})
You bound to the div not the button.
give the button a name or select it as a child then bind the click event.
<div id='back'>
<input id='backbutton' type="button"/>
</div>
JQuery
$('#backbutton').click(clickOnBackbutton);
function clickOnBackbutton(){
console.log('back to menu'); //function not called
}
This should work:
function clickOnBackButton(){
console.log("back to menu");
}
$('#back').click(function(){
clickOnBackButton();
});
You could do this
$('#back').click(function(){
clickOnBackButton();
});
I don't think there's such a thing as an input type="button". Maybe type="submit" ?
Also you can use:
$('#back').on('click', function(){
// some action
});
JQuery 1.7+ you should attach the event using on.
function clickOnBackbutton(){
console.log('back to menu'); //function not called
}
$(document).on("click", "#back", clickOnBackbutton);
Running example
If you want div#back to capture clicked button event, then with the recent jquery you have to do this:
$('#back').on("click", "input[type=button]", clickOnBackbutton);
Note that you have to put script tag in the end of body, or wrap your code in $(document).ready event.

How to check if there is already a click/event associated to an element

lets say I have
function trigger(){
$('a.pep').each(function(){
$('a.pep').click(function(){
console.log($(this).val());
});
});
}
function push(){
$('body').append('<a class="pep">hey mate i have no trigger yet</a>');
trigger(); //now i do but the others have duplicated trigger
}
$(document).ready(function(){
$('a.push').click(function(){
push();
});
});
So it seems that the click event is being applied twice/+ because the console.log is lauched more than once by click
How can i prevent this?
The problem is that you call $('a.pep').click() lots of times. (In fact, you bind as many click handlers as there are matching elements to each element. And then you do it again every time one of them is clicked.)
You should lever the DOM event bubbling model to handle this. jQuery helps you with the on method:
$(document.body).on('click', 'a.pep', function() {
console.log('element clicked');
$(document.body).append('<a class="pep">Click handlers handled automatically</a>');
});
See a working jsFiddle.
Note that I have removed the val call, because a elements can't have a value... Note also that the on method is introduced in jQuery 1.7; before that, use delegate:
$(document.body).delegate('a.pep', 'click', function() {
Small change to your trigger function is all you need. Just unbind the click event before binding to ensure that it is never added more than once. Also, you don't need to use each when binding events, it will add the event to each item automatically.
function trigger(){
$('a.pep').unbind('click').click(function() {
console.log($(this).val());
});
}
You can check using data('events') on any element if the required event is attached or not. For example to check if click event is attached or not try this.
if(!$('a.pep').data('events').click){
$('a.pep').click(function(){
console.log($(this).val());
});
}
you should use jQuery live here because you add DOM elements dynamicly and you want them to have the same click behaviour
function push(){
$('body').append('<a class="pep">hey mate i have no trigger yet</a>');
}
$(document).ready(function(){
$('a.push').click(function(){
push();
});
$('a.pep').live('click', function(){
console.log($(this).val());
});
});
Try:
if($('a.pep').data('events').click) {
//do something
}
i think if you use live() event you dont need to make function
$('a.pep').live('click', function(){
console.log($(this).val());
});

Categories