I have added a click event to a div:
div.addEventListener('click', function(event) { ... });
Later I dynamically add a span with innerHTML:
div.innerHTML = "<span>some text</span>"
Now the text is not clickable, which surprises me, because I thought the click event would propagate up and trigger the click handler on the parent div. What is going on?
I have recreated the problem with jsfiddle. I don't understand what is going on.
/
I have added a click event to a div:
div.addEventListener('click', function(event) { ... });
Later I dynamically add a span with innerHTML:
div.innerHTML = "<span>some text</span>"
Now the text is not clickable, which surprises me, because I thought the click event would propagate up and trigger the click handler on the parent div. What is going on?
I have recreated the problem with jsfiddle. I don't understand what is going on.
http://jsfiddle/3n5s3ez9/
Share Improve this question edited Apr 14, 2023 at 21:47 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Nov 9, 2014 at 23:29 Fletcher MooreFletcher Moore 13.8k11 gold badges42 silver badges59 bronze badges 2- 1 You might want to provide more information. Here's a jsfiddle to describe your situation: link – Milan Commented Nov 9, 2014 at 23:36
- Thanks. I am actually having a lot of difficulty recreating the error in jsfiddle. Forces are at play that I do not understand. – Fletcher Moore Commented Nov 10, 2014 at 0:14
5 Answers
Reset to default 9 +50There's nothing magical going on, you don't see a click-event happen, because a click-event is never fired. The reason is due to the behaviour of browsers generating the events. I refer to this FIDDLE to explain what happens.
- A
click-event
is triggered on an element after that element has first got amousedown
and then amouseup
. If one of them is missing the click is not performed. - A
mouseover
is triggered when 1) the pointer enters the element, 2) when the pointer is moved on the element, 3) after each mousedown on the element, and 4) after each mouseup on the element. (Firefox additionally fires it continuously as long as the pointer is on the element, but that doesn't matter here). - Each time we do
innerHTML =
the existing HTML is deleted and a new span is created. In the fiddle I have added a number to the span-text which increases each time that happens.
Let's evaluate what happens when you enter the div and click on the span stepwise:
- Enter the div:
mouseover
is triggered and the span is created byinnerHTML
. This span is number 0. - Move on the div until reaching the span:
mouseover
is triggered many times, and each time a new span is created. Lets say we end up with span20. - Click on the span: First a
mousedown
is triggered on the existing span20. Immediately afterwards amouseover
is fired which deletes span20 and creates span21. When the mousebutton is released amouseup
is triggered on span21. Because that span has not received amousedown
before no click-event is performed. After mouseupmouseover
fires again, deletes span21 and creates span22.
If you perform the actions slowly and watches the console its easy to track these steps. The second div in the fiddle has not a click- but a mouseup
-handler, and you find that event fired each time button is released.
Try setting a background color on the div so you can see if you're actually clicking on what you expect. I find divs are often not where I expect them to be.
Your problem is that the 'mouseover' listener is constantly firing on your div which leads to constantly adding a new span which then triggers it again, causing your clicks on the span element to not propagate.
I created a fiddle where the span is only added once:
http://jsfiddle/3n5s3ez9/59/
var d = document.getElementById("hello");
var missionAcplished = false;
d.addEventListener("click", function(event) {
alert(event);
});
d.addEventListener("mouseover", function (event) {
console.log('triggered');
if (!missionAcplished) {
d.innerHTML = "<span>Hello World</span>";
missionAcplished = true;
}
});
Looks like an evil loop.
I think you need to get the element firstly.
var div = document.getElementsByTagName("div");
div.addEventListener('click', function(event) { ... }, true);
div.innerHTML = "<span>some text</span>"
Your code is pretty close I have made a slight adjustment that works
The HTML:
The Javascript:
//get elementsByTagName
//you have to add the [0] index in order for
//to get the div from the collection of div elements stored
//in the div variable
var div = document.getElementsByTagName("div")[0];
div.addEventListener('click', function(event) {
alert("it works");
});
div.innerHTML = "<span>Hello World</span>";