简体   繁体   English

点击事件没有传播

[英]Click event not propagating up

I have added a click event to a div 我已将div事件添加到div中

div.addEventListener('click', function(event) { ... });

Later I dynamically add a span with innerHTML. 稍后,我使用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. 现在,文本不可单击,这使我感到惊讶,因为我认为click事件将传播并触发父div上的click处理程序。 What is going on? 到底是怎么回事?

I have recreated the problem w/ jsfiddle. 我已经用jsfiddle重新创建了问题。 I don't understand what is going on. 我不明白发生了什么。

http://jsfiddle.net/3n5s3ez9/ http://jsfiddle.net/3n5s3ez9/

There'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. 我参考这个FIDDLE来解释会发生什么。

  • A click-event is triggered on an element after that element has first got a mousedown and then a mouseup . 在该元素上先click-event mousedown然后在mouseup上触发click-event 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. 当1)指针进入元素时; 2)指针在元素上移动时; 3)每次将鼠标移到元素上之后; 4)每次将鼠标移到元素上之后,就会触发mouseover (Firefox additionally fires it continuously as long as the pointer is on the element, but that doesn't matter here). (只要指针位于元素上,Firefox还会连续触发它,但这并不重要)。
  • Each time we do innerHTML = the existing HTML is deleted and a new span is created. 每次我们执行innerHTML =删除现有HTML并创建新的跨度。 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: 让我们评估一下当您输入div并逐步单击跨度时会发生什么:

  • Enter the div: mouseover is triggered and the span is created by innerHTML . 输入div:触发mouseover ,并且span由innerHTML创建。 This span is number 0 . 范围是数字0
  • Move on the div until reaching the span: mouseover is triggered many times, and each time a new span is created. 在div上移动直到到达跨度:多次触发mouseover ,并且每次创建新的跨度。 Lets say we end up with span20 . 可以说我们以span20结尾
  • Click on the span: First a mousedown is triggered on the existing span20 . 单击范围:首先,在现有范围20上触发mousedown Immediately afterwards a mouseover is fired which deletes span20 and creates span21 . 之后立即触发mouseover ,从而删除span20并创建span21 When the mousebutton is released a mouseup is triggered on span21 . 当mousebutton被释放的mouseup扳机span21。 Because that span has not received a mousedown before no click-event is performed . 因为在未执行click-event之前,该跨度尚未收到mousedown After mouseup mouseover fires again, deletes span21 and creates span22. mouseup mouseover再次触发后,删除span21并创建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. 小提琴中的第二个div不是click-,而是mouseup -handler,您会发现每次释放按钮时都会触发该事件。

Try setting a background color on the div so you can see if you're actually clicking on what you expect. 尝试在div上设置背景颜色,这样您就可以查看自己是否实际点击了期望的颜色。 I find divs are often not where I expect them to be. 我发现div通常不在我期望的位置。

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: HTML:

The Javascript: 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>";

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. 您的问题是“ mouseover”侦听器会不断在您的div上触发,从而导致不断添加新的跨度,然后再次触发它,从而导致您对span元素的点击不传播。

I created a fiddle where the span is only added once: 我创建了一个小提琴,其中跨度仅添加一次:

http://jsfiddle.net/3n5s3ez9/59/ http://jsfiddle.net/3n5s3ez9/59/

var d = document.getElementById("hello");
var missionAccomplished = false;
d.addEventListener("click", function(event) {
    alert(event);
});
d.addEventListener("mouseover", function (event) {
    console.log('triggered');
    if (!missionAccomplished) {
        d.innerHTML = "<span>Hello World</span>";
        missionAccomplished = true;
    }
});

Looks like an evil loop. 看起来像一个邪恶的循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM