停止事件冒泡 - onclick 侦听器

Stop event bubbling - onclick listener

为什么点击父 div 元素可以完成工作,但点击子 div 文本 Click Me! returns undefined 而页面却没有无法在 iframe 中加载?我用 event.stopPropagation 来停止冒泡,但它仍然是一样的。当 addEvenLisneter 优于内联 onclick 时,正确的方法是什么?

var panel = document.getElementsByClassName('panel');
var iframe = document.getElementById('frame');

[].forEach.call(panel, function(each) {
    each.addEventListener('click', linkClick);
});

function linkClick ( event ) {
    event.stopPropagation();
    event.preventDefault();
    iframe.src = event.target.dataset.url;
}
.panel {
    padding: 20px;
    margin: 10px;
    border: 1px solid yellow;
}

.panel div {
  display: inline;
}
<div class="panel" data-url="https://www.w3schools.com/jsref/event_preventdefault.asp">
  <div>Click Me!</div>
</div>
<iframe id="frame"></iframe>

当我console.log(event)泡泡属性仍然设置为真

如果您阻止点击事件从内部 div 冒泡,那么它永远不会到达您绑定事件处理程序的事件,您的函数将根本不会触发。

这里的问题是 event.target 与实际点击的元素匹配。如果要获取事件处理程序绑定到的元素,则需要 event.currentTarget

var panel = document.getElementsByClassName('panel');
var iframe = document.getElementById('frame');

[].forEach.call(panel, function(each) {
    each.addEventListener('click', linkClick);
});

function linkClick ( event ) {
    event.stopPropagation();
    event.preventDefault();
    iframe.src = event.currentTarget.dataset.url;
}
.panel {
    padding: 20px;
    margin: 10px;
    border: 1px solid yellow;
}

.panel div {
  display: inline;
}
<div class="panel" data-url="https://www.w3schools.com/jsref/event_preventdefault.asp">
  <div>Click Me!</div>
</div>
<iframe id="frame"></iframe>

好吧,我实际上并不是在解决问题本身,更像是一种变通方法。

也许您可以尝试使用按钮,因为这样更有效 HTML。

我修改了 CSS 一点,所以它符合你的例子。

<!DOCTYPE html>
<html>
<style>
.panel {
    padding: 20px;
    margin: 10px;
    border: 1px solid yellow;
    display:block;
    width:100%;
    text-align:left
}

</style>
<body>

<button class="panel" data-url="https://www.w3schools.com/jsref/event_preventdefault.asp" type="button">Click Me!</button>
<iframe id="frame"></iframe>

</body>
<script>
var panel = document.getElementsByClassName('panel');
var iframe = document.getElementById('frame');

[].forEach.call(panel, function(each) {
    each.addEventListener('click', linkClick);
});

function linkClick ( event ) {
    event.stopPropagation();
    event.preventDefault();
    iframe.src = event.target.dataset.url;
}
</script>
</html>