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

如何阻止拖拽事件透过元素边框泄漏到底层容器?

Angular ngx-dnd嵌套放置区拖拽事件穿透问题

我在Angular中使用Swimlane ngx-dnd实现嵌套放置区的拖拽功能:最底层的chapter大div是放置区,内部用CSS模拟的表格里,每个单元格div也是放置区。将单元格内的可拖拽元素在单元格间拖拽时,拖拽事件偶尔会触发到底层的chapter div,干扰精准放置操作。

这个问题仅在单元格带有边框时出现,我怀疑是鼠标恰好停留在边框上时,浏览器生成的拖拽事件未被单元格捕获,反而穿透到了chapter。

ngx-dnd会接管所有浏览器原生拖拽事件,替换为仅在指定放置区div上触发的自定义事件。我曾尝试在单元格和chapter之间新增div拦截原生事件,但无效,因为代码无法获取到原生事件。

请问如何阻止拖拽事件透过边框泄漏到底层chapter div?或者我的问题诊断是否有误?


复现代码

HTML代码

<div id="test">
 <div class="test-chapter">
  <div ngxDroppable="test-dropzone" (drag)="DragChapter($event)" (over)="OverChapter($event)">
   <div class="test-table-container">
    <div class="test-table" (drag)="DragTable($event)" (over)="OverTable($event)">
     <div style="display:contents">
      <div class="test-row-container">
       <div class="test-row" (drag)="DragRow($event)" (over)="OverRow($event)">
        <div style="display:contents">
         <div class="test-cell-container">
          <div class="test-cell" ngxDroppable="test-dropzone" (drag)="DragCell($event)" (over)="OverCell($event)">
          </div>
         </div>
        </div>
        <div style="display:contents">
         <div class="test-cell-container">
          <div class="test-cell" ngxDroppable="test-dropzone" (drag)="DragCell($event)" (over)="OverCell($event)">
          </div>
         </div>
        </div>
        <div style="display:contents">
         <div class="test-cell-container">
          <div class="test-cell" ngxDroppable="test-dropzone" (drag)="DragCell($event)" (over)="OverCell($event)">
          </div>
         </div>
        </div>
       </div>
      </div>
     </div>
     <div style="display:contents">
      <div class="test-row-container">
       <div class="test-row" (drag)="DragRow($event)" (over)="OverRow($event)">
        <div style="display:contents">
         <div class="test-cell-container">
          <div class="test-cell" ngxDroppable="test-dropzone" (drag)="DragCell($event)" (over)="OverCell($event)">
          </div>
         </div>
        </div>
        <div style="display:contents">
         <div class="test-cell-container">
          <div class="test-cell" ngxDroppable="test-dropzone" (drag)="DragCell($event)" (over)="OverCell($event)">
           <div class="test-content">
            <div class="test-content-class">
             <p>drag me</p>
            </div>
           </div>
          </div>
         </div>
        </div>
        <div style="display:contents">
         <div class="test-cell-container">
          <div class="test-cell" ngxDroppable="test-dropzone" (drag)="DragCell($event)" (over)="OverCell($event)">
          </div>
         </div>
        </div>
       </div>
      </div>
     </div>
     <div style="display:contents">
      <div class="test-row-container">
       <div class="test-row" (drag)="DragRow($event)" (over)="OverRow($event)">
        <div style="display:contents">
         <div class="test-cell-container">
          <div class="test-cell" ngxDroppable="test-dropzone" (drag)="DragCell($event)" (over)="OverCell($event)">
          </div>
         </div>
        </div>
        <div style="display:contents">
         <div class="test-cell-container">
          <div class="test-cell" ngxDroppable="test-dropzone" (drag)="DragCell($event)" (over)="OverCell($event)">
          </div>
         </div>
        </div>
        <div style="display:contents">
         <div class="test-cell-container">
          <div class="test-cell" ngxDroppable="test-dropzone" (drag)="DragCell($event)" (over)="OverCell($event)">
          </div>
         </div>
        </div>
       </div>
      </div>
     </div>
    </div>
   </div>
  </div>
 </div>
</div>

CSS代码

.test-chapter {
  position: relative;
  width: 500px;
  padding: 20px;
  border: 1px solid lightgrey;
  background-color: white;
}

.test-table-container 
{
  position: relative;
  min-height: 30px;
  cursor: grab;
  padding: 20px;
  background-color: #bce9b3;
}

.test-table
{
  width: 100%;
  table-layout: fixed;
  display: table;
  border-collapse: collapse;
}

.test-row-container {
  min-height: 30px;
  border-radius: 3px;
  cursor: default;
  position: relative;
  display: table-row-group;
}

.test-row {
  display: table-row;
}

.test-cell-container
{
  display: table-cell;
  vertical-align: top;
  cursor: default;
  position: relative;
  border: 1px solid #8b8b8b;
  background-color: #b6cdf7;
}

.test-cell
{
  min-height: 20px;
}

.test-content
{
  cursor: pointer;
  position: relative;
  cursor: pointer;
  background-color: #f59fb9;
}

.test-content-class
{
  min-height: 20px;
  border: dashed thin #8b8b8b;
  color: black;
}

调试用JavaScript代码

DragChapter(event)
{
  console.log('drag chapter');
}

OverChapter(event)
{
  console.log('over chapter');
}

DragTable(event)
{
  console.log('drag table');
}

OverTable(event)
{
  console.log('over table');
}

DragCell(event)
{
  console.log('drag cell');
}

OverCell(event)
{
  console.log('over cell');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:15:11