如何防止拖拽孩子,但允许拖拽父母?

时间:2011-07-27 16:47:10

标签: javascript html5 drag-and-drop

我有一个用户可以拖动的div,div里面是一个带有一些文本的跨度,我想让用户选择(因此他们无法拖动它)。如何允许div拖动,而不是跨度?

dragstart事件在div上。

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

dragstart(大致):

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部分按预期工作,但我无法阻止拖动并允许选择。

6 个答案:

答案 0 :(得分:4)

仅发布以防有人使用类似问题搜索

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

为我工作

答案 1 :(得分:3)

你可以将子元素更改为draggable并在ondragstart时防止默认,这会在子元素上保留常规行为,而父元素仍然可以拖动

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

HTML:

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

答案 2 :(得分:3)

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

<div draggable="true" ondragstart="console.log('dragging')">
    <span>Drag me! :)</span>
    <input draggable="true"
           ondragstart="event.preventDefault();
                        event.stopPropagation();"
           value="Don't drag me :(">
</div>

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

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

答案 3 :(得分:2)

在跨度上放置一个mousedown处理程序,并在那里停止事件传播。

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

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

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

document.addEventListener('mousedown', function (event) {
	var 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);
div{
  display:block;
  background: black;
  padding: 5px;
  margin: 2px;
}
<html>
  <body>
    <div class="drop_content" draggable="true">
      <input value="Can't drag me">
    </div>
    <div class="drop_content" draggable="true">
      <input value="Can't drag me either">
    </div>
  </body>
</html>