如何使用jQuery UI使元素可拖动,但不包括其子元素?

22

例如,我想要这样做:

<div class="draggable">
<p>Text that can be selected</p>
</div>

@AymanSafadi,我一开始也是这么想的。但不是这样的:我相当确定他希望用户能够选择段落中包含的文本,而不会启动可拖动父元素上的拖动操作。 - David Thomas
3个回答

33
你可以使用cancel选项,它接受一个选择器来指定不允许拖拽的可拖动对象的子元素:
$('.draggable').draggable({cancel : 'p'});

JS Fiddle演示


1
这适用于p元素,但子元素可以是任何元素,甚至是文本节点。问题是“但不包括其子元素”。对此有什么想法吗? - Timo Kähkönen
我添加了一个答案,提供了一种可能的方法来选择所有子节点和其他文本节点的方法。 - Timo Kähkönen

10

除了 p 标签之外,可能还有其他元素作为子元素。在这种情况下,您需要使用空格选择器:

$(".draggable").draggable({cancel: ".draggable *"});

工作示例在JSFIDDLE上。

它使用空格选择器,该选择器选择元素的所有子元素,无论它们是子元素还是孙子元素。空格选择器的示例请参见w3schools

缺点是所有文本节点都必须包含在标签内,例如span、div、p等。如果它们不在标签内,*选择器无法匹配它们。为了保持纯文本节点可选,您必须使用更复杂的代码,因为CSS和jQuery没有用于纯文本节点的选择器。例如,您可以使用自己的标签来包装文本节点。自定义节点的原因是减少了意外样式化此自定义元素的可能性(例如使用span等),在此情况下,我们将其命名为“custom”:

$(".draggable").draggable({cancel:'.draggable *'})
.contents().filter(function() {return this.nodeType == Node.TEXT_NODE;})
.wrap('<custom></custom>');

上述内容在JSFIDDLE上。现在普通文本节点也可以选择了。如果您随后添加更多文本节点到可拖动的元素中,则情况会发生变化。然后您必须再次将它们包装。


0

您可以通过初始化选项来覆盖start函数。在此处返回false将会提前退出。要访问单击时创建的鼠标事件,您可以在jQuery事件上访问originalEvent属性。

$(".draggable").draggable({
  start: function(event, ui) {
    return event.originalEvent.target === this;
  }
});

这样可以只允许父级元素可拖动。你可以将this替换为任何你想要成为唯一可拖动项的元素,只需确保它是被比较的dom节点。

Plunkr示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接