Reputation: 751
I have the following HTML content:
<span onclick="alert('Boem')">
<button id="test1">test</button>
</span>
When I call the following JavaScript code:
$('#test1').trigger('click');
The onclick event is triggered twice, while I expect it to just trigger once. Because jQuery should look up in the DOM tree and find only one onclick.
I do not have control of the span, it is generated in a third party tool. I do have control over the button and his parameters.
You can find a JSFiddle example here: http://jsfiddle.net/Voga/v4100zke/
I do not know the contents of the onclick listener of the span. This is also generated by the third-party tool. I want the click trigger to execute this onclick like it does now, but only once.
Upvotes: 42
Views: 128867
Reputation: 1
In my case I add event listener on a parent div which trigger click event. In this event listener I need to trigger click event on hidden input. So the second click call the first and I got 2 calls. To avoid this behavior I dd event listener on the input to stop propagation event.
item.addEventListener('click', (event) => {
event.stopPropagation();
event.preventDefault();
var checkbox = item.querySelector('input[type="checkbox"]');
if (checkbox) {
checkbox.click();
item.classList.toggle('is-selected');
}
});
item.querySelector('input').addEventListener('click', function (event) {
// Avoid that the click on checkbox trigger parent event.
event.stopPropagation();
})
});
Upvotes: 0
Reputation: 1
In my case don't have a nested button, but I had the same problem. I solved adding 'return false;' at the end of the event.
$('#test1').click(function() {
alert('Boem');
return false;
});
Upvotes: 0
Reputation: 28523
It is calling twice because the button is inside a span and span has onclick="alert('Boem')"
, hence when you trigger click on the button then it shows an alert and the same click event propagates to span and shows the alert once again.
You need to stop default behaviour of button using below code:
$(function(){
$('#test1').click(function(e){e.preventDefault();}).click();
});
Upvotes: 40
Reputation: 26382
To stop event propagation, use: stopPropagation
$( "#test1" ).on( "click", function(ev) {
ev.stopPropagation();
});
$('#test1').trigger('click');
Please note the order events are assigned in DOM.
Upvotes: 13
Reputation: 549
This question will help answer the 'why' of it.
A better way would be to just assign a click handler to the element so as to keep your JavaScript code abstracted out of the HTML:
http://jsfiddle.net/v4100zke/3/
$('#test1').click(function() {
alert('Boem')
});
Upvotes: 0
Reputation: 9
Note that you have used jQuery's click method. It will emit both the DOM's mouse click event and jQuery's click event. Then both jQuery's click event and DOM's mouse click event are propagated to the span element and its onclick listener is triggered twice, hence it alerts twice.
Check this demo to figure it out.
As for how to deal with it, just use stopPropagation as in previous answers.
$('#test1').click(function() {
// comment this line and run, 'parent' will be alerted TWICE!!! since both mouseEvent and jQuery.Event trigger the onclick listener
$('#children').click(function(e) {e.stopPropagation()})
});
Upvotes: 0
Reputation: 1
This happens because of bubbling. This is because, as javascript.info says: "events “bubble” from the inner element up through parents like a bubble in the water".
If your third-party tool generates your <span></span>
element with the onclick
attribute included, this probably means that your tool wants you to treat your span directly as your button, without the necessity of creating an additional one as you're doing with your <button></button>
element.
Here, to fix this error, the best way is to programmatically click the same element that contains the handler to avoid propagation:
$('#test1').trigger('click');
/* Now, you can take #test1 and make it look and function as a button */
#test1 {
padding: 10px 20px;
color: white;
background-color: #0078d7;
font-size: 2rem;
font-family: Helvetica;
}
#test1:hover {
cursor: pointer;
background-color: blue;
transition: all 0.25s;
}
<!-- Script to include jQuery v3.3.1 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="test1" onclick="alert('Boem')">test</span>
Upvotes: 0
Reputation: 2225
I was also getting a similar issue where I had to download a pdf which was downloading twice. I used jQuery's stopImmediatePropagation method.
$( "#test1" ).on("click", function(e) {
e.stopImmediatePropagation();
});
$('#test1').trigger('click');
stopImmediatePropagation will prevent any parent handlers and also any other handlers from executing. Refer here for more details.
Upvotes: 36
Reputation: 1659
I also face this problem on Modal
Solved by the following tricks -
$('#saveButton').off('click').on('click', { modal: modal }, save)
Here off('click')
prevents the save method fires multiple times.
Upvotes: 1
Reputation: 1913
I had the same problem. Mine was the fact that I was using .trigger('.element')
and there were two elements with that element
class.
So, I got more specific, and used .trigger('.parent .element')
to ensure only one click event happened on a single element, instead of one click event on two elements.
Upvotes: 0
Reputation: 5309
Here button click is triggered
. Since the button
is inside the span
and onclick
event is defined for span
the two alert
are happened.
One is by the button
and
other by its parent
(parent have onclick event and button click is triggered).
To avoid two alert, use this
<span>
<button onclick="alert('Boem')" id="test1">test</button>
</span>
Upvotes: 0
Reputation: 164
Bubbling. The click event on the child also happens on the parent (span).
Upvotes: 6