How do I avoid one 'click' that triggers two functions? - javascript

Hi I have two JS functions:
$('button').click(function() inside $(document).ready
$(document).on('click','button', function()
the second function is design for buttons that I dynamically generated.
The problem I have is that when I click the button that associates with first function, the second function also gets triggered. How can I avoid this?
PS: since I give names to each button and this conflict is not affecting functionalities at all, but I think that one click trigger two function is not very smart :(

That is because of event propagation.
You can stop the event propagation in the first handler to prevent the dynamic handler from being fired.
$('button').click(function (e) {
e.stopPropagation();
//your code
})
But a more appropriate solution will be to add a common class to all the dynamic button elements and target only them with the delegated handler like
<button class="mydynamic"></button>
then
$(document).on('click','button.mydynamic', function(){
});

You can find documentation for event.stopPropagation() here

Wrap your dynamicly generated buttons into a div:
<div class="wrap">...buttons... </div>
and listen on the div:
$('.wrap').on('click','button', function(){});
It will be more efficent.

Related

jQuery .off() not removing handlers

I have a dynamically loaded button created when the document loads. After this, I attach a click handler to this button. When I try to remove the handler with .off(), it does not work.
This snippet creates the click handler and removes it. However, when I click the button, the function StartMash still executes.
$(document).on("click", "#mash-idle-start", StartMash);
$("#mash-idle-start").off();
Obviously this is not the functionality I am trying to achieve, but the problem persists through this simple example
because the event handler is not attached to #mash-idle-start, it is attached to document so
$(document).off("click", "#mash-idle-start", StartMash);
or
$(document).off("click", "#mash-idle-start");
Note: When working with event unbinding, try to use event namespaces as you will have more control over which handlers are removed.

Jquery click event propagation on second click after Ajax

Hi i always use this example code to make a div work as link.
<div onclick="location.href='http://www.example.com';" style="cursor:pointer;"></div>
The problem is i have inserted an other javascript action inside (this action need to stay on the current page) the problem is Not the first click but the second..
This javascript actions its an ajax function that "change" that html.. in the fiddle where i have no ajax, its working great, on first, second, third, any clic..
Here is the code http://jsfiddle.net/HzsH9/4/
Im using.. Jquery, also this is the anti propagate code im using
$("a").bind("click", function(e){ alert("clicked!"); e.stopPropagation() });
The outer div class is class="listingsRow"
and the inside javascript goes here
<a id="btn_remove_114" name="btn_remove_114" onclick="ajaxFavouratesRemove(1,114,375);">
<div class="fav"></div></a>
After ajax success, its changed for this
<span id="spadd114"><a id="btn_add_114" name="btn_add_114" onclick="ajaxFavouratesAdd(114);"><div class="nofav"></div></a></span>
Also i just found this, but i cant manage to do the same how to stop event propagation with slide toggle-modified with the updated code.
Classic case of event delegation
$(".listingsRow").on('click','a',function(e){
alert('clicked');
e.stopPropagation();
})
$('#singles_114').click(function(e){
e.stopPropagation()
});

button click event triggering wrong event handler

I have a div display some titles of music which is clickable. When you click it it will show some more detail information. Then I also have a button in the clickable div. When I click the button. It won't call the function of the button but the function of the div? Is there a way to solve this? Thank you!
$("#myComList").append("<div id="+comListID+" class=listDiv> <p class=comTitle><? echo $row["compositionTitle"] ?>(<?echo $row["year"]?>)</p><button id="+comListID+"btn class=addNewArrBtn>Add new Arrangement</button> <p class=comOri>BY <? echo $row["OrigComposer"] ?></p> </div>");
$('#'+comListID).click(function() {
$(this).find("li").slideToggle('slow', function() {
});
$("#"+comListID+"btn").click(function(){
addNewArr(comListID);
});
It's called 'bubbling'. The button is inside the div so it's executing button then up the chain to div. Add event.stopPropagation() inside the button function.
$("#"+comListID+"btn").click(function(event){
event.stopPropagation();
addNewArr(comListID);
});
From jQuery documentation:
By default, most events bubble up from the original event target to
the document element. At each element along the way,
jQuery calls any matching event handlers that have been attached.
A handler can prevent the event from bubbling further up the document
tree (and thus prevent handlers on those elements from running) by
calling event.stopPropagation(). Any other handlers attached on the
current element will run however. To prevent that, call
event.stopImmediatePropagation(). (Event handlers bound to an element
are called in the same order that they were bound.)
http://api.jquery.com/on/
So you'd call event.stopPropagation() inside the button click handler, as to stop the div event from firing.
I believe I understand your question without seeing the code. The problem it sounds like stems from the click event bubbling or propagating up. Below is a sample of code to try and a link to a fiddle for you to test:
<div id="testDiv" onclick="alert('Stop Clicking Me!');">
<button type="button" onclick="function(e) { alert('You hit the button!'); e.stopPropagation(); }">Click Me!</button>
</div>
In this function, the:
e.stopPropagation();
prevents the click event from filtering up to its parent container (in this case "testDiv") and triggering its click event as well. You can test it and see for yourself in the jsfiddle below:
Test Fiddle
EDIT:
In your case:
$("#"+comListID+"btn").click(function(e){
addNewArr(comListID);
e.stopPropagation();
});
add the event parameter to the click function and stop it from propagating to the parent.
Hope this helps.

How do I assign click handlers to each child with jquery?

<div id="menu">
<div class="menuitem-on" id="home">Home</div>
<div class="menuitem-off" id="mycart">My Cart</div>
<div class="menuitem-off" id="shop">Shop</div>
</div>
how do I assign click handlers to each of the children of menu with jquery?
$("#menu").delegate('div','click', function(){
//do your thing here
});
Handler is on parent, so only one. You can add more div without changing code.
Here is a fiddle page to show a couple of different selector options to get the click anywhere, or just the first level. Shows the use of the event target, currentTarget as well: http://jsfiddle.net/8GLZJ/
Update 3/18/2013 for 1.9.1+ jQuery use:
$("#menu").on('click','div', function(){
//do your thing here
});
You don't want to do that because:
You create a event handler for each children
If you dynamically add more elements, the handler won't work for them.
A better solution is to add a single event handler to the parent element and then do a different action based on the event.target property, that contains the clicked element.
This happens because of event bubbling and it's a cool feature you should take advantage of.
jQuery in particular abstracts this under what they call live events so you should go with those.
$("#menu div").click(function(){
// your code goes here
// $(this) give you the element that was clicked
});
Binding event to each one of element using click() or bind('click', ...) isn't a good solution, because in case if you have, lets say 50 items, you will have to bind 50 same handlers - browser has to register them all.
Better solution is to use feature called event delegation - and jQuery has special method for that - delegate(). So your code will look like this:
$('#menu').delegate('div', 'click', function() {
//code of your handler - 'this' refers to clicked element
});
There is an article with video showing difference between click, live and delegate in jQuery: NetTuts+.
Something like
$("#menu div").on('click', function(){
//alert('clicked');
});

Is it possible to have jQuery.click trigger on the top element only?

I'm trying to make a site where the user can click on any element to edit it's CSS. I use the following to add the click function to all <li>, <div> and <ul>.
$('li,div,ul').click(function () {
alert(this.id);
});
The problem is if I click on a <li> element, then I get the alert for that and any element underneath it. (all the containers).
Is it possible to have only the top element trigger when clicked?
You want to stop event propagation, you do this in jQuery by calling the stopPropagation method on the event object.
$('li,div,ul').click(function (e) {
e.stopPropagation();
alert(this.id);
});
I believe you'd want to use stopPropagation(); inside the click function.
It sounds to me like you're looking for .stopPropagation(). Calling stopPropagation will prevent the event from "bubbling" up to parent containers.

Categories