Javascript 父节点上的事件侦听器也在所有子节点上触发
我从头开始用vanilla js编写了一个draggable类(这与jQuery draggable无关),它工作得很好,只有我的侦听器在所选节点的子节点上触发。我在监听器中尝试了Javascript 父节点上的事件侦听器也在所有子节点上触发,javascript,ecmascript-6,addeventlistener,getelementsbyclassname,stoppropagation,Javascript,Ecmascript 6,Addeventlistener,Getelementsbyclassname,Stoppropagation,我从头开始用vanilla js编写了一个draggable类(这与jQuery draggable无关),它工作得很好,只有我的侦听器在所选节点的子节点上触发。我在监听器中尝试了e.stopPropagation(),但似乎没有改变结果 下面是该类的一段代码: setListeners() { const targets = document.getElementsByClassName("-jsDraggable"); [...targets].forEach(elem
e.stopPropagation()
,但似乎没有改变结果
下面是该类的一段代码:
setListeners() {
const targets = document.getElementsByClassName("-jsDraggable");
[...targets].forEach(elem => {
elem.addEventListener("mousemove", e => this.handleMouseMove(e));
elem.addEventListener("mousedown", e => this.handleMouseDown(e));
elem.addEventListener("mouseup", e => this.handleMouseUp(e));
});
}
。。。例如:
<ul class="-jsDraggable">
<li>No drag</li>
<li>No drag</li>
<li class="-jsDraggable">Can drag this item</li>
<li>No drag</li>
</ul>
- 无阻力
- 无阻力
- 可以拖动此项目
- 无阻力
在这种情况下,我希望…
和内部的单个…
都受到影响,从其他列表项中拖动只需拖动主…
元素即可
但是,无论我与哪个子节点交互,无论它在DOM中与类的节点相比有多远,它都会触发处理程序
任何帮助都将不胜感激
编辑:另一个澄清的例子:
<article class="-jsDraggable">
<header>
<h1>Heading</h1>
</header>
<main>
<p>...</p>
</main>
</article>
标题
无论我在这个
元素中拖动到哪里,它都应该将整个HTML组作为一个整体拖动(因为它的父元素都有这个类)。然而,目前它的行为更像这样:
<article class="-jsDraggable">
<header class="-jsDraggable">
<h1 class="-jsDraggable">Heading</h1>
</header>
<main class="-jsDraggable">
<p class="-jsDraggable">...</p>
</main>
</article>
标题
。。。每个孩子也都在移动,而它应该只移动附加了类的父容器。如果我正确理解了你的问题,那么一个选项(除其他外)是区分事件的起源,并通过事件
对象的当前目标
和目标
字段过滤事件处理,如下所示:
if(event.currentTarget === event.target) {
/* The user is interacting with the actual -jsDraggable element */
}
else {
/* The user is interacting with a descendant of a -jsDraggable element */
}
这实际上意味着,如果生成事件的元素(即currentTarget
)与事件处理程序绑定到的元素(即target
)相同,则我们确定事件与实际的-jsDraggable
元素本身(而不是后代)相关。此方法补充了您当前的代码,如下所示:
功能handleMouseMove(事件){
if(event.currentTarget==event.target){
log(Date.now(),'Mouse move over draggable');
}
}
功能handleMouseDown(事件){
if(event.currentTarget==event.target){
log(Date.now(),'draggable上的Drag start');
}
}
功能handleMouseUp(事件){
if(event.currentTarget==event.target){
log(Date.now(),'draggable上的Drag end');
}
}
函数setListeners(){
const targets=document.queryselectoral(“-jsDraggable”);
targets.forEach(elem=>{
元素addEventListener(“mousemove”,e=>handleMouseMove(e));
元素addEventListener(“鼠标向下”,e=>handleMouseDown(e));
元素addEventListener(“mouseup”,e=>handleMouseUp(e));
});
}
setListeners()代码>
ul{
填充:1rem;
背景:浅绿色;
}
李{
填充:1rem;
背景:粉红色;
}
-jsDraggable{
背景:浅蓝色;
}
- 无阻力
- 无阻力
- 可以拖动此项目
- 无阻力
我解决了它,它不起作用,因为我将当前元素设置为this.elem=e.target
,而不是this.elem=e.currentTarget
。在此之后,鼠标向下中的e.stopPropagation()
按预期工作
感谢您让我接触到e.currentTarget
,在阅读此线程中的帮助之前,我没有意识到这一点。停止事件传播应该可以。您可以演示一下您使用它的尝试吗?我想您希望只有当e.target
是-jsDraggable
时才会触发mousedown
事件,否则,当单击的子项不是-jsDraggable
时,也会触发处理程序。(不完全确定您想在mousemove和mouseup上做什么,您可能也不想在那里进行检查)(live snippet将大大有助于调试问题)我只希望包含类-jsDraggable
的元素移动,但目前,嵌套在类节点中的每个节点都是可拖动的。仅停止事件传播本身就有问题。这确实会阻止子节点触发,但父节点也不会触发(不会发生任何事情)。期望的效果是,即使在与子节点交互时,如果父节点具有类,它也应该触发父节点的功能