You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于preventDefault函数的异常行为疑问

关于dragstart事件中preventDefault影响子元素拖拽的问题解释

问题描述

对preventDefault的工作机制存在困惑:在示例中,给elem2的dragstart事件监听添加event.preventDefault()后,elem2无法拖拽符合预期,但拖拽elem3时,它的拖拽事件也被取消了——明明elem3的事件处理器里并没有调用preventDefault。

补充背景:拖拽可拖拽元素时,dragstart事件会在目标元素及其所有祖先元素上触发。此处事件捕获设为false,事件按elem3→elem2→elem1的顺序冒泡。未添加preventDefault时三个元素都可拖拽,添加后elem3也失效,原因不明。

核心原因

dragstart事件的默认行为是启动整个拖拽操作,只要事件传播路径(捕获/冒泡阶段)上的任意一个事件监听器调用了preventDefault(),整个拖拽操作就会被取消,不管这个监听器属于目标元素还是祖先元素。

当拖拽elem3时:

  1. 事件先在elem3触发,其处理器未阻止默认行为;
  2. 事件冒泡到elem2,这里的处理器调用了preventDefault(),直接取消了拖拽的默认启动行为;
  3. 最终整个拖拽操作无法启动,elem3的拖拽自然失效。

解决方法

如果需要实现「elem2不能拖拽,但elem3可以拖拽」的效果,只需在elem2的事件处理器中判断事件的目标是否为elem2本身,仅当目标是elem2时才阻止默认行为:

function elem2EventHandler(event) {
  console.log("target: " + event.target.id);
  console.log("currentTarget: " + event.currentTarget.id);
  // 仅当触发事件的目标是elem2自身时,阻止拖拽启动
  if (event.target === event.currentTarget) {
    event.preventDefault();
  }
}

完整代码示例

JavaScript

const elem1 = document.getElementById("elem1");
elem1.addEventListener("dragstart", elem1EventHandler, false);

const elem2 = document.getElementById("elem2");
elem2.addEventListener("dragstart", elem2EventHandler, false);

const elem3 = document.getElementById("elem3");
elem3.addEventListener("dragstart", elem3EventHandler, false);

function elem1EventHandler(event) {
  console.log("target: " + event.target.id);
  console.log("currentTarget: " + event.currentTarget.id);
}

function elem2EventHandler(event) {
  console.log("target: " + event.target.id);
  console.log("currentTarget: " + event.currentTarget.id);
  if (event.target === event.currentTarget) {
    event.preventDefault();
  }
}

function elem3EventHandler(event) {
  console.log("target: " + event.target.id);
  console.log("currentTarget: " + event.currentTarget.id);
}

CSS

#elem1 {
  display: block;
  position: relative;
  width: 200px;
  height: 150px;
  background-color: deepskyblue;
}

#elem2 {
  display: block;
  width: 150px;
  height: 100px;
  background-color: greenyellow;
}

#elem3 {
  display: block;
  width: 100px;
  height: 50px;
  background-color: coral
}

HTML

<div id="elem1" draggable="true">
  <div id="elem2" draggable="true">
    <div id="elem3" draggable="true">
    </div>
  </div>
</div>

内容的提问来源于stack exchange,提问作者Dante

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 07:10:24