将Javascript Dragenter和Dragleave事件拖到孩子上方时不会触发

时间:2018-12-06 09:18:58

标签: javascript html drag-and-drop

我有以下小提琴,希望可以帮助我解释我的意思:https://jsfiddle.net/czh6efx7/4/

以下HTML和样式

logged <- reactiveVal(value = F)

# change the value of logged() when a user enters correct credentials

output$your_ui <- renderUI({
   req(logged())
   # your ui here...
})

以及与此相关的脚本

<div id="a">
  <div id="b">

  </div>
</div>

<div id="draggable" draggable="true"></div>

#a {
  background: green;
  padding: 25px;
}

#b {
  background: red;
  padding: 50px;
}

#draggable {
  padding: 20px;
  background: blue;
}

我添加了document.getElementById('a').addEventListener('dragenter', function(e) { if(e.target.id === 'a') { console.log("DRAG ENTER"); } }); document.getElementById('a').addEventListener('dragleave', function(e) { if(e.target.id === 'a') { console.log("DRAG LEAVE"); } }); 检查来尝试解决此问题,但是它似乎不符合我的预期。

无论如何,我遇到的确切问题是if(e.target.id === 'a') {#b的子级,并且我不希望将#a首先拖到{ {1}},然后是孩子(#draggable)。 #a#b并非如此,因此mouseentermouseleave的工作方式似乎与此不同。

您应该能够在带有以下复制步骤的小提琴中看到这一点:

  • 开始拖动蓝色框
  • 将蓝色框拖动到绿色框的外部 -确认已记录dragenter,很好
  • 立即将其拖动到红色框中 -请注意已记录dragleave,因为红色框是绿色框的子元素,所以这不好,因此,就我要实现的目标而言,我们仍然感到困惑在绿色盒子上,尽管是绿色盒子的孩子。
    • 从红色框拖回到绿色框 -请注意,DRAG ENTER再次被触发,再次不理想,因为就我而言,用户已经进入绿色框的拖动状态。

我的意图是,当用户拖动到DRAG LEAVE上时,只记录DRAG ENTER,而当用户从DRAG ENTER上拖动时,无论它是否滑过,都只记录#a DRAG LEAVE的孩子。

我还应该提到#a的这些子元素将是交互式的,因此我不能使用#a来解决此问题。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我可以看到dragenterdragleave在内部子对象上被触发的用处,但是在您希望内部包含其他元素的情况下,这很棘手。

您可以改用dragover,然后在特定时间后检测是否触发了该事件吗?例如:

const $a = document.getElementById('a');

const enterHandler = ($a) => { console.log('enter a') };
const leaveHandler = ($a) => { console.log('leave a') };

let timer = null;
$a.ondragover = (e) => {
  clearTimeout(timer);
  enterHandler($a);
  timer = setTimeout(() => leaveHandler($a), 100);
}

提琴:https://jsfiddle.net/eguhbr90/