Reputation: 4873
I have a simple div with a link with in:
<div class="mhButton">
<a href="#" id="RegisterAnimal"><span class="icon-checkmark"></span> Register Animal</a>
</div>
I've have a function that is triggered whenever the 'div.mhButton' is clicked. This function should find 'div.mhButton' child 'a' and click it.
$(".mhButton").on('click', function () {
var a = $(this).find("a").text();
console.log(a);
$(this).find("a").click();
});
This works, however, I get stuck in a loop that runs like 639 times.
I can't comprehend why this runs X amount of times, then continues without error.
Does anyone have a solution on how to prevent this? Along with an explanation on why this happens?
Note* The console is logging the same button, again and again.
Upvotes: 1
Views: 709
Reputation: 92274
When you call $(this).find("a").click();
the event will bubble up to the div.mhButton
tag and cause your handler to be called again. The reason it runs around 500 times is because it stops with a stack overflow, it does not continue
You can prevent it by checking if the click was the <a>
tag itself and not calling click()
in that case
Working example: http://jsfiddle.net/mendesjuan/zdkrhh42/
Note Regarding the accepted answer
Bic's second answer almost works, mine is a different approach with fewer side effects. The main problem with calling stopPropagation
is that there may be handlers on the whole document that wouldn't get fired in that case. A commmon case is when you have a menu or a dialog that is supposed to hide when you click anywhere else on the page. The stopPropagation
approach will prevent the menu from being hidden when they click your button.
$(".mhButton").click(function (e) {
// Only run this handler if the click was on the div, not the link itself
if ( $(e.target).is('a, a *') ) {
return;
}
var a = $(this).find("a").text();
$(this).find("a").click();
});
Upvotes: 1
Reputation: 3134
Because the a
tag is embedded in the button, you are continuously re-firing the event. Events will bubble up, so the anchor will get clicked, and then its parent. It is running until the browser gets tired of running it and then it just stops. The method doesn't actually do anything which is likely why you aren't seeing any issues. You can accomplish your goal a couple of ways:
$(".mhButton").click(function () {
$(this).off('click'); // turn the click handler off in the handler itself.
var a = $(this).find("a").text();
console.log(a);
$(this).find("a").click();
});
If you do this, then you will end up only being able to fire the event once.
Alternatively:
$(".mhButton").click(function (e) {
a = $(this).find("a").text();
console.log(a);
$(this).find("a").click();
});
$("#RegisterAnimal").click(function (e) {
e.stopPropagation(); // prevent the anchor from re-firing the button click
});
Altenatively, you can just style the link to look like a button and avoid the unnecessary click handlers all together.
Upvotes: 2