No-API:如何防止点击父级?

时间:2016-09-29 08:00:15

标签: javascript javascript-events parent-child

我制作了自己的拖放系统,其中包括制作包含其他元素的div元素(=可拖动元素)。我不使用jQuery或HTML5。

以下是它的工作原理:

  

当用户触发MouseDown事件时,我们使元素可拖动。     然后:如果,当他触发MouseUp事件(即拖动结束)时,程序检测到他没有移动元素,这意味着它只是一个简单的点击。     否则,这意味着它是一个实际拖拽。     因此,程序能够以正确的方式行动(即根据拖拽或简单点击的存在)     只需单击一下即可隐藏元素的内容。否则,元素将被删除(=变得不可拖动)。

我的问题是:当我单击窗口中的某个元素时,它就会被隐藏。这意味着可以处理可拖动元素的事件。

我想阻止在用户点击其中一个元素时点击可拖动元素。

你知道我怎么能干净利落地做到这一点吗?如果需要,请不要问我代码。

2 个答案:

答案 0 :(得分:0)

  

我希望阻止在用户点击其中一个元素时点击可拖动元素。

在您的事件处理程序中要做的第一件事:检查event.target是否与this相同。如果没有,请立即退出。否则:您确定被点击的div而不是其中一个孩子。

演示:

document.getElementById('dv').addEventListener('mousedown', function (e) {
    if(e.target !== this) {
      console.log('skip');
      return; // skip
    }
    console.log('mousedown');
});
div {
  border: 1px solid;
  padding: 10px;
}
<div id="dv">
   test test: mouse down here
   <div>don't respond on this nested element
      <div>And not on this one either</div>
   </div>
   mouse down here
</div>

替代方案:停止传播

实现相同目标的另一种方法是停止将事件传播到元素的父元素:

document.getElementById('child').addEventListener('mousedown', function (e) {
    console.log('skip');
    e.stopPropagation();
});

document.getElementById('dv').addEventListener('mousedown', function (e) {
    console.log('mousedown');
});
div {
  border: 1px solid;
  padding: 10px;
}
<div id="dv">
   test test: mouse down here
   <div id="child">don't respond on this nested element
      <div>And not on this one either</div>
   </div>
   mouse down here
</div>

答案 1 :(得分:0)

  

如果x移动和y移动的距离小于10mouseDownmouseUp之间的差异大于300,用户即将发起click事件或继续Drag-Drop事件!

iScroll.js引用伪代码:

var point = e.touches ? e.touches[0] : e,
  deltaX = point.pageX - this.pointX,
  deltaY = point.pageY - this.pointY,
  timestamp = utils.getTime(),
  newX, newY,
  absDistX, absDistY;

this.pointX = point.pageX;
this.pointY = point.pageY;

this.distX += deltaX;
this.distY += deltaY;
absDistX = Math.abs(this.distX);
absDistY = Math.abs(this.distY);

// We need to move at least 10 pixels for the scrolling to initiate
if (timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10)) { // Click event
  return;
}