关于javascript:如何防止拖拉孩子,但允许拖拉父母?

How do I prevent drag on a child, but allow drag on the parent?

我有一个div可供用户拖动,该div内是一个跨度,其中包含一些文本,我希望允许用户选择(因此他们无法拖动它)。 如何允许div拖动而不允许跨度拖动?

dragstart事件在div上。

我可能忽略了一些简单的事情。 我在div上尝试draggable = true,在跨度上尝试draggable = false。 那没用。 尝试在dragstart上返回false,但这也不起作用。

dragstart(大致):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var jTarget = $(e.target);
if ((jTarget.is('div.header') || (jTarget.parents('div.header'))
       && !jTarget.is('a, input, span')))
{
   e.originalEvent.dataTransfer.setData("Text","test");
}
else
{
   if(e.preventBubble)
      e.preventBubble();
   if(e.stopPropagation)
      e.stopPropagation();
   return false;//???
}

if else部分按我的预期工作,但是我什么也无法停止拖动并允许选择。


如果要真正取消拖动并使父拖动处理程序不注意到它,则需要同时preventDefaultstopPropagation

1
2
3
4
5
    <span>Drag me! :)</span>
    <input draggable="true"
           ondragstart="event.preventDefault();
                        event.stopPropagation();"

           value="Don't drag me :(">

如果没有stopPropagation,即使将阻止默认行为(event.defaultPrevented == true),仍将调用父ondragstart。如果该处理程序中有无法处理这种情况的代码,则可能会看到细微的错误。

当然,您也可以将JavaScript放在element.addEventListener('dragstart', ...)内。


只是发布,以防有??人搜索类似问题

1
2
element.addEventListener('mousedown', function() { this.parentNode.setAttribute("draggable", false); });
element.addEventListener('mouseup', function() { this.parentNode.setAttribute("draggable", true); });

为我工作


您可以将子元素更改为可拖动,并在ondragstart时阻止默认设置,这将保留子元素的常规行为,而父元素仍可拖动

1
function drag(e){ if(e.target.type=="range")e.preventDefault();/*rest of your code*/  }

的HTML:

1
<input type="range" draggable="true" ondragstart="drag(event)">


将mousedown处理程序放在跨度上,并在该处停止事件传播。


我从这里的一些答案中得到了启发,我想我想出了最干净,最可重用的解决方案。我使用鼠标按下事件来检查元素是否应该可拖动。我通过验证它是否具有仅分配给可拖动元素的特定类名来进行此操作。在mouse up事件上,我遍历了带有该class标签的所有元素,并将它们的可拖动值设置回true。

如果输入节点是可拖动div的深子级节点,则可能会中断,但是您可以使用与mouse up事件中相同的算法,并将所有值设置为false。

1
2
3
4
5
6
7
8
9
10
11
12
13
document.addEventListener('mousedown', function (event) {
\tvar clickedElem = event.target;
    if(!clickedElem.classList.contains("drop_content")){
        clickedElem.parentElement.setAttribute("draggable",false);
    }
}, false);

document.addEventListener('mouseup', function () {
    var boxes = document.querySelectorAll(".drop_content");
    for(var i = 0; i < boxes.length; i++){
        boxes[i].setAttribute("draggable",true);
    }
}, false);
1
2
3
4
5
6
div{
  display:block;
  background: black;
  padding: 5px;
  margin: 2px;
}
1
2
3
4
5
6
7
8
9
10
<html>
  <body>
   
      <input value="Can't drag me">
   
   
      <input value="Can't drag me either">
   
  </body>
</html>


在我的应用程序中,我无法获得此处列出的任何其他解决方案。这对我有用:

1
ondragstart="event.preventDefault();" draggable="false"

在我的特定情况下,它是在div中输入的文本。