为啥单击和拖动会导致父元素成为`event.target`?

Posted

技术标签:

【中文标题】为啥单击和拖动会导致父元素成为`event.target`?【英文标题】:Why does clicking and dragging cause the parent element to be the `event.target`?为什么单击和拖动会导致父元素成为`event.target`? 【发布时间】:2019-01-21 16:12:22 【问题描述】:

在定期点击子 div 时,以下代码将打印被点击的特定子 div 的 ID。

<div id="parent">
  <div id="A" class="child"></div>
  <div id="B" class="child"></div>
</div>

<script>
  $("#parent").on('click', event => 
     $(event.target).text(event.target.id)
  )
</script>

但是,如果您单击一个子元素 div 并在另一个子元素 div 中拖动/释放,那么它将打印父元素的 ID。

当点击处理程序分配给子项时,不会发生这种情况。

$(".child").on('click', event => 
    $(event.target).text(event.target.id)
)

为什么在第一个例子中拖拽动作导致事件目标是父元素?

http://jsfiddle.net/thz1esfc/

澄清为什么不重复What is event bubbling and capturing?:

我了解事件冒泡和捕获与“为什么”相关,但仅说明它是事件冒泡或捕获并不能解释该场景。它没有解释为什么子元素 A 上的 mousedown 和子元素 B 上的 mouseup 会导致父元素成为 event.target 而不是单击开始的子元素 A 或释放单击的子元素 B。

这两个似乎试图解释结果,但如果可能的话,我想要一些显示这种行为的文档。

从技术上讲,浏览器在父 b/c 上注册 CLICK,第一次或第二次都不会注册完整的 CLICK(意味着 mousedown 和 mouseup)

由浏览器来处理该行为。至少在 Firefox 上,当您单击一个框并拖动到另一个框并释放时,单击事件会丢失。

【问题讨论】:

What is event bubbling and capturing?的可能重复 事件冒泡和捕获绝对是正在发生的事情的一部分,但该链接并未详细介绍此特定场景。它没有解释为什么触发第一个子元素的点击并拖动/释放到第二个子元素会导致父元素成为event.target @MicFin 没有第二个子元素 - 第二个子元素是父元素的子元素,而不是第一个子元素。 我会改写澄清。 “它没有解释为什么触发对子元素 A 的点击并拖动/释放到子元素 B 会导致父元素成为 event.target。” 【参考方案1】:

这发生在您身上,因为从技术上讲,点击事件是在释放点击时触发的,而不是在实际点击本身时触发的。见:https://developer.mozilla.org/en-US/docs/Web/Events/click

你可以mousedown,效果会更准确:

$("#parent").on('mousedown', event => 
	$('#message').text(event.target.id)
)
#parent 
  width: 300px;
  height: 300px;
  background-color: cyan;


.child 
  height: 100px;
  width: 100px;
  background-color: grey;
  border: 1px solid black;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
  <div id="1" class="child">
  
  </div>
   <div id="2" class="child">
  
  </div>
</div>
<p id="message">
</p>

编辑:当您单击并拖动到下一个子项以显示“父项”时,cmets 询问为什么 - 这是事件冒泡。您需要使用 event.stopPropagation() 来阻止它。

【讨论】:

点击事件在技术上是在发布时触发!!当您在孩子内部释放时,为什么会显示 parent 而不是 id 如果我在另一个子 div 上释放,为什么另一个子 div 不是目标?为什么假设发布在父母身上而不是另一个孩子身上? @MicFin 基本上这里发生的是事件冒泡。在此处查看更多信息:***.com/questions/4616694/… @ZakariaAcharki, @MicFin,因为在这种情况下,点击的唯一共同元素是parent (对于点击 = 按下 + 释放) 从技术上讲,浏览器注册 CLICK在parent b/c 上,第 1 次或第 2 次都没有注册完整的 CLICK @kawnah 你能解释为什么parent 是目标,而不是鼠标按下/单击的child A 或鼠标按下/释放的child B。 @serg 是否正确,浏览器未识别 child Achild B 注册完整点击,因此 parent 接收点击?【参考方案2】:

由浏览器来处理该行为。至少在 Firefox 上,当您单击一个框并拖动到另一个框并释放时,单击事件会丢失。

【讨论】:

这准确吗?您可以分享有关该规范的任何文档吗?听起来确实可以解释这种行为。

以上是关于为啥单击和拖动会导致父元素成为`event.target`?的主要内容,如果未能解决你的问题,请参考以下文章

在 safari 浏览器中,子元素不会成为父元素的焦点

使用 UIPanGestureRecognizer 的可拖动视图中的操作元素导致视图移动

可拖动元素的遏制

为啥父元素不包含边距?

使用子元素拖动父元素

css父元素和子元素,我点击父元素让其隐藏,但为啥点击子元素也会隐藏?