Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 父节点上的事件侦听器也在所有子节点上触发_Javascript_Ecmascript 6_Addeventlistener_Getelementsbyclassname_Stoppropagation - Fatal编程技术网

Javascript 父节点上的事件侦听器也在所有子节点上触发

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

我从头开始用vanilla js编写了一个draggable类(这与jQuery draggable无关),它工作得很好,只有我的侦听器在所选节点的子节点上触发。我在监听器中尝试了
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
    的元素移动,但目前,嵌套在类节点中的每个节点都是可拖动的。仅停止事件传播本身就有问题。这确实会阻止子节点触发,但父节点也不会触发(不会发生任何事情)。期望的效果是,即使在与子节点交互时,如果父节点具有类,它也应该触发父节点的功能