拖动子项时防止父项上的单击事件 [英] Prevent a click event on parent when children are being dragged
问题描述
我看到几个 类似问题.他们都说调用event.stopPropagtion()
".我正在调用 event.stopPropagation()
但我仍然收到关于父母的点击事件.我做错了什么?
I see a couple of similar questions. All of them say "call event.stopPropagtion()
". I'm calling event.stopPropagation()
but I'm still getting click events on parents. What am I doing wrong?
let dragTarget;
let dragMouseStartX;
let dragMouseStartY;
let dragTargetStartX;
let dragTargetStartY;
const px = v => `${v}px`;
function dragStart(e) {
e.preventDefault();
e.stopPropagation();
dragTarget = this;
const rect = this.getBoundingClientRect();
dragMouseStartX = e.pageX;
dragMouseStartY = e.pageY;
dragTargetStartX = (window.scrollX + rect.left) | 0;
dragTargetStartY = (window.scrollY + rect.top) | 0;
window.addEventListener('mousemove', dragMove, {passive: false});
window.addEventListener('mouseup', dragStop, {passive: false});
}
function dragMove(e) {
if (dragTarget) {
e.preventDefault();
e.stopPropagation();
const x = dragTargetStartX + (e.pageX - dragMouseStartX);
const y = dragTargetStartY + (e.pageY - dragMouseStartY);
dragTarget.style.left = px(x);
dragTarget.style.top = px(y);
}
}
function dragStop(e) {
e.preventDefault();
e.stopPropagation();
dragTarget = undefined;
window.removeEventListener('mousemove', dragMove);
window.removeEventListener('mouseup', dragStop);
}
document.querySelector('.drag').addEventListener('mousedown', dragStart);
document.body.addEventListener('click', () => {
console.log('body clicked', new Date());
});
body { height: 100vh; }
.drag {
background: red;
color: white;
padding: 1em;
position: absolute;
user-select: none;
cursor: pointer;
}
<div class="drag">drag and release me</div>
推荐答案
问题是您正在监听 mousedown 事件.click
event 和 mousedown
event 是不同类型的事件,因此要修复您的代码必须添加以下内容:
The problem is you're listening the mousedown event. click
event and mousedown
event are different types of events, so to fix your code must add this:
document.querySelector('.drag').addEventListener('click', e => e.stopPropagation());
这样做您将拦截子级中的事件,您可以根据需要处理它.
Doing this you're going to intercept the event in the children and you can handle it as you want.
let dragTarget;
let dragMouseStartX;
let dragMouseStartY;
let dragTargetStartX;
let dragTargetStartY;
const px = v => `${v}px`;
function dragStart(e) {
e.preventDefault();
e.stopPropagation();
dragTarget = this;
const rect = this.getBoundingClientRect();
dragMouseStartX = e.pageX;
dragMouseStartY = e.pageY;
dragTargetStartX = (window.scrollX + rect.left) | 0;
dragTargetStartY = (window.scrollY + rect.top) | 0;
window.addEventListener('mousemove', dragMove, {passive: false});
window.addEventListener('mouseup', dragStop, {passive: false});
}
function dragMove(e) {
if (dragTarget) {
e.preventDefault();
e.stopPropagation();
const x = dragTargetStartX + (e.pageX - dragMouseStartX);
const y = dragTargetStartY + (e.pageY - dragMouseStartY);
dragTarget.style.left = px(x);
dragTarget.style.top = px(y);
}
}
function dragStop(e) {
e.preventDefault();
e.stopPropagation();
dragTarget = undefined;
window.removeEventListener('mousemove', dragMove);
window.removeEventListener('mouseup', dragStop);
}
document.querySelector('.drag').addEventListener('mousedown', dragStart);
document.querySelector('.drag').addEventListener('click', e => e.stopPropagation());
document.body.addEventListener('click', () => {
console.log('body clicked', new Date());
});
body { height: 100vh; }
.drag {
background: red;
color: white;
padding: 1em;
position: absolute;
user-select: none;
cursor: pointer;
}
<div class="drag">drag and release me</div>
这篇关于拖动子项时防止父项上的单击事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!