gpt4 book ai didi

javascript - 只在 div 内监听点击而不干扰它的 child (一个 hitbox)?

转载 作者:行者123 更新时间:2023-11-30 15:24:37 26 4
gpt4 key购买 nike

我有以下 DOM 结构:

#container {
position: absolute;
width: 100px;
height: 100px;
background-color: blue;
}

#content {
position: absolute;
width: 90%;
height: 90%;
background-color: yellow;
}

#content_child {
position: absolute;
width: 30px;
height: 30px;
left: 150px;
top: 150px;
background-color: red;
}
<div id="container">
<div id="content">
<div id="content_text">Hello</div>
<div id="content_child"></div>
</div>
</div>

#content_text#content_child 会有各种鼠标事件。我想检测 #container 上的鼠标事件。但是,如果我只是将事件附加到 #container,它们将被它的 child 激活,这是不希望的。我的要求如下(我以点击事件为例):

  • 当点击#container时,我希望它的事件被触发
  • 当一个 child 图形位于其div(如#content_text)被点击时,我想要 child 的和#容器要触发的事件
  • 当点击以图形方式其div(如#content_child)的 child 时,我希望 child 的事件触发

我事先知道哪些 child 将在 div 的外部和内部。

我可以想到两种方法,但都存在很大缺陷:

  1. 将鼠标事件附加到 #container,并为 div 外部的每个子级添加与附加到 #container 的事件相同的事件,但使处理程序不执行任何操作,并且使它们不传播。这有点笨拙。
  2. 添加“命中区域”/“命中框”div...某处。这将是一个透明的 div,它是 #container 的子项(并且大小相同),它会注册点击,这不会传播到它的 sibling 的子项,即 #content 的 child ,因为他们是 sibling 。如果我将它放在 #content 之前,所有 hitbox 的事件都会被 #content 吃掉并且它们永远不会触发。如果我把它放在后面,反过来也是同样的问题。我不能让他们同时在同一个地方收听相同的事件,而不将它们传递给他们所有的 child 。

有没有一种方法可以在不进行重大重组或花哨的 Javascript 的情况下实现类似 hitbox 的行为(我使用的是 Elm,所以两者都不是一个选项)?

最佳答案

将处理程序附加到 #container。当您收到该事件时,如果它通过一个图形上在容器外部的子项,请忽略它。

您可以通过检查事件对象上的 target 和(如果需要)它的 parentNode 等来确定点击到达容器的路径,直到你到达容器。

这是一个例子(在这个例子中,我硬编码了检查子项是否在父项中的图形,因为你说过你已经知道了;不需要去搞清楚它的工作举个简单的例子):

function hook(selector, event, handler) {
var elements = document.querySelectorAll(selector);
Array.prototype.forEach.call(elements, function(el) {
el.addEventListener(event, handler, false);
});
}
// container's click handler
hook("#container", "click", function(e) {
if (passedThroughChildOutsideBox(e, this)) {
// Ignore
} else {
console.log("container click");
}
});
// child handlers
hook("#content_text, #content_child", "click", function(e) {
console.log(this.id + " click");
});

// Fake detection
function passedThroughChildOutsideBox(e, container) {
var node = e.target;
while (node && node !== container) {
if (node.id === "content_child") { // Again, just hardcoded for demo
return true;
}
node = node.parentNode;
}
return false;
}
#container {
position: absolute;
width: 100px;
height: 100px;
background-color: blue;
}

#content {
position: absolute;
width: 90%;
height: 90%;
background-color: yellow;
}

#content_child {
position: absolute;
width: 30px;
height: 30px;
left: 150px;
top: 150px;
background-color: red;
}
<div id="container">
<div id="content">
<div id="content_text">Hello</div>
<div id="content_child"></div>
</div>
</div>

关于javascript - 只在 div 内监听点击而不干扰它的 child (一个 hitbox)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43184950/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com