拖放事件传播

问题描述 投票:0回答:1

我正在尝试在我的项目中设置拖放功能

我有几个像这样的字段设置 如果用户单击左侧的图像并拖动,他们可以重新排序行

当检测到有效的拖放区时(在这种情况下,任何其他行都是有效的拖放区),一个类将应用于包装该行的所有元素的 div,该类在下方呈现一个边框以指示将插入拖放的行的位置

我的问题是,出于某种原因,如果我将一行拖到作为拖放区子级的

input
select
元素之一上,它们将被视为拖放区而不是底层元素。 它有点难以看到,但最右边的输入下方有一条虚线,表明我的 dropzone 类已添加。

如何设置

每个有效的 dropzone 都会调用以下 JS

function dropzone(node, options) {
  console.log(`created dropzone on ${node}`);
  let state = {
    dropEffect: "move",
    dragover_class: ["dropzone", "pb-3"],
    ...options,
  };

  function handle_dragenter(e) {
    console.log(`DragEnter ${e.target}`);
    e.stopPropagation();
    e.target.classList.add(...state.dragover_class);
  }

  function handle_dragleave(e) {
    console.log(`DragLeave ${e.target}`);
    e.stopPropagation();
    e.target.classList.remove(...state.dragover_class);
  }

  function handle_dragover(e) {
    console.log(`DragOver ${e.target}`);
    e.stopPropagation();
    e.dataTransfer.dropEffect = state.dropEffect;
  }

  node.addEventListener("dragenter", handle_dragenter, true);
  node.addEventListener("dragleave", handle_dragleave, true);
  node.addEventListener("dragover", handle_dragover, true);
}

我尝试过的

CSS

我尝试将

pointer-events: none;
添加到我的
dropzone
类的所有子级中,这些子级添加到我的
dragenter
处理程序中,该处理程序有效,但仅当在其任何子级之前成功进入拖放区时才有效。我还尝试过在 dropzone 的所有子元素上设置空白设置
pointer-events: none;
,这确实解决了问题,但也阻止了输入工作

JS

我尝试在通过

useCapture
添加事件侦听器并在所有处理程序中调用
addEventListener
时将
e.stopPropagation()
设置为 true,据我了解,这应该会导致事件侦听器添加到的节点(在本例中, dropzone row)在传播到所有子级之前首先被调用。但是,输入仍在接收
dragenter
事件

useCapture
感觉是最有前途的方法,但我必须在这里遗漏一些东西(或者由于某种原因它不适用于拖动事件)。

任何人都可以看到我的设置有任何明显的错误,或者可以向我提供任何其他建议来解决我的问题吗?

javascript drag-and-drop svelte
1个回答
0
投票

重构 HTML 将是理想的方法,但您也可以...

将这些事件添加到您不想成为拖放区域的所有子项:

e.ondrop='';

e.ondragover='';

“快速而肮脏”的修复。

© www.soinside.com 2019 - 2024. All rights reserved.