【问题标题】:Clicking inside element and dragging mouse outside it单击内部元素并将鼠标拖动到其外部
【发布时间】:2015-10-28 11:18:57
【问题描述】:

我确定有人已经遇到过这样的问题,但不幸的是我找不到答案。

window.onload = function (e) {
    var foo = document.getElementById('foo');
    foo.addEventListener('click', function(e) {
      e.stopPropagation();
      e.preventDefault();
      alert('foo');
    });
    document.body.addEventListener('click', function(e) {
      alert('body');
    });
};
#foo {
  width: 200px;
  height: 200px;
  background-color: red;
  cursor: pointer;
}
body,
html {
  width: 100%;
  height: 100%;
}
<div id="foo">Click me</div>

请参阅jsfiddle 和 我将逐步描述我的问题:

1) 点击红色的 div 2) 不要松开鼠标键拖到外面

如您所见,主体点击功能已触发。这就是我要禁用的。我想检测用户是否在 div 内部单击,然后他/她将其拖到外部,则一定不会发生任何事情!

【问题讨论】:

  • event.stopImmediatePropagation() 可以特别解决这个问题。
  • 我认为你在玩错误的事件!尝试使用 mousedown 和 mouseup。并且玩拖动这很有用:drag,dragend,dragleave,dragenter,dragover,dragstart ...来自MDN
  • 这也很有趣 - 即使mouseup 位于另一个没有冒泡事件的元素上,它仍然会触发click bodyjsfiddle.net/y0q8rw0g

标签: javascript html drag-and-drop onclick


【解决方案1】:

看起来 Firefox 是唯一一个在光标离开原始元素时不触发点击的浏览器。在与 webkit 相关的浏览器上,没有原始 mousedown 的踪迹,但所有事件数据都基于这样一个事实,就好像在 body 上触发了一次完整的点击一样。所以没有办法根据点击本身来区分。可能有一些解决方法,但这里有一个 - 检查是否有任何点击来自元素上的 mousedown

window.addEventListener('load', function() {

var foo = document.getElementById('foo'), fromfoo,
origin  = document.getElementById('origin');

foo.addEventListener('mousedown', function(e) {

    e.stopPropagation();

    fromfoo = true;
});

document.body.addEventListener('mousedown', function() {

    fromfoo = false;
});

foo.addEventListener('mouseup', function(e) {

    e.stopPropagation();

    if (fromfoo) origin.innerHTML = 'foo';
});

document.body.addEventListener('mouseup', function() {

    if (fromfoo) origin.innerHTML = 'different';
    else origin.innerHTML = 'body';
});
});
html, body {
  width:100%;
  height:100%;
  margin: 0;
}

#origin {
  float: right;
  margin: 50px 100px;
}

#foo {
  width:200px;
  height:200px;
  background-color: red;
  cursor:pointer;
}
<div id="origin"></div>
<div id="foo">Click me</div>

这是一个很好的解决方法,但部分原因是因为它与 Mozilla 反向兼容。

编辑 - 很奇怪这是 Microsoft documentation 所说的:

例如,如果用户在对象上单击鼠标,但在释放之前将鼠标指针从对象上移开,则不会发生 onclick 事件。

但似乎根本不是这样。


更新 - 经过多次搜索也找到了这份报告:

https://code.google.com/p/chromium/issues/detail?id=484655

所以这似乎至少是错误的行为或对 W3 规范的误解。显然是 IE 的一个已知问题和最近出现在 Chrome 中的一个问题。这个 2013 年关于 IE 的问题看起来也只是相关的。有人发布了一个小插件,可能仍然很有趣:

Internet Explorer leaks click event after adding an overlay in a jQuery mousedown handler

【讨论】:

  • 对不起'忽略',确实你的回答很有帮助,我也有这样的想法,但解决方案并不完美。我会期待理想的,如果没有人出现,会选择你的答案作为解决方案!
  • 感谢您的回复 - 对不耐烦感到抱歉。我对此进行了广泛的研究,也记录了事件本身并在每个细节上进行了比较。 body 的幻觉点击似乎与直接点击它相同。不幸的是,无法阻止点击本身,只能阻止它们的默认操作以及它们是否会冒泡的事实。所以我认为没有办法使用这些不同的事件。与所有浏览器匹配似乎有点过于复杂,但看起来不可避免。您发布的一个非常有趣的问题在 Google 上显示为空结果。
  • 是的,我也认为没有人会找到更好的解决方案,但让我们再等一天,然后我会检查你的答案!再次感谢朋友的帮助!
  • 如果有人提供更好的解决方案,我很高兴看到它,并且一定会支持。干杯。
【解决方案2】:

用途:

e.stopImmediatePropagation();

防止调用同一事件的其他侦听器。

来源 MDN:https://developer.mozilla.org/en-US/docs/Web/API/Event/stopImmediatePropagation

window.onload = function (e) {
    var foo = document.getElementById('foo');
    foo.addEventListener('click', function(e) {
      e.stopImmediatePropagation();
      e.preventDefault();
      alert('foo');
    });
    document.body.addEventListener('click', function(e) {
      alert('body');
    });
};
#foo {
  width: 200px;
  height: 200px;
  background-color: red;
  cursor: pointer;
}
body,
html {
  width: 100%;
  height: 100%;
}
&lt;div id="foo"&gt;Click me&lt;/div&gt;

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-30
  • 1970-01-01
  • 2019-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多