拖动子项时防止父项上的单击事件 [英] Prevent a click event on parent when children are being dragged

查看:31
本文介绍了拖动子项时防止父项上的单击事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到几个 类似问题.他们都说调用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 事件.clickevent 和 mousedownevent 是不同类型的事件,因此要修复您的代码必须添加以下内容:

The problem is you're listening the mousedown event. clickevent and mousedownevent 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆