我的目的是拥有一系列文件夹和子项(如目录树),然后拖放项目以重新排列。当我只是点击一个文件夹(带有子ul的列表项)时,它应该滑开或滑动关闭。
问题是:我想在取消拖动时阻止点击事件。
取消 - 我的意思是我开始拖动元素,然后释放鼠标而不将其放在任何可放置的顶部。
我的第一个猜测是使用event.stopImmediatePropagation()
和event.stopPropagation()
。当我取消没有ul子项的列表项的拖动时,这确实会阻止click事件。
但是,当我取消对具有ul子项的li的拖动时,会发生默认的单击行为(在本例中为slideToggle)。
当我取消拖动带有ul儿童的li时,如何防止点击事件?
$("li").click(function (event) {
console.log($(this).attr("class"));
if ($(this).children("ul").length > 0) $(this).children("ul").slideToggle();
event.stopPropagation();
event.stopImmediatePropagation();
event.preventDefault();
})
$("li").draggable({
rever: false,
helper: "clone",
cursorAt: {
top: -1,
left: -1
},
stop: function (event) {
event.stopPropagation();
event.stopImmediatePropagation();
}
});
$("span").droppable({
hoverClass: "ui-state-active",
greedy: true,
tolerance: "pointer",
drop: function (event, ui) {
var dragged = ui.draggable
var target = $(this).parent()
if (target.children("ul").length == 1) {
dragged.appendTo(target.children("ul"));
} else {
// depends upon whether I'm dragging from above or from below
if (dragged.prev().is(target)) // dragging from below
dragged.insertBefore(target)
else dragged.insertAfter(target)
}
event.stopPropagation();
},
});
中的完整代码
答案 0 :(得分:1)
一种解决方法是使用单独的元素来触发这两个动作。
例如,我们使用handle
选项。
如果指定,则限制从开始拖动,除非在指定元素上发生了mousedown。只允许从可拖动元素下降的元素
触发拖动,并使用单独的<span>
元素触发切换功能。
Updated Fiddle(点击要拖动的文字,+
/ -
进行切换)
另一个 hackish 解决方法是跟踪布尔标志 -
我们可以在拖动开始时将boolean
设置为true
,并在停止回调中的微小超时后将其设置回false
。
当我们释放鼠标时会立即触发click事件 - 所以如果通过拖动触发点击,布尔标志仍然是true
,因为我们只会在短暂超时后重置它。如果是正常点击 - 该标志将为false。
var dragging = false;
$("li").click(function (event) {
event.stopPropagation();
$this = $(this);
console.log(dragging);
if (!dragging) {
if ($this.children("ul").length > 0) $this.children("ul").slideToggle();
}
});
$("li").draggable({
revert: false,
helper: "clone",
cursorAt: {
top: -1,
left: -1
},
start: function (event) {
dragging = true;
},
stop: function (event) {
setTimeout(function () {
dragging = false;
}, 10);
}
});
$("span").droppable({
hoverClass: "ui-state-active",
greedy: true,
tolerance: "pointer",
drop: function (event, ui) {
var dragged = ui.draggable
var target = $(this).parent()
if (target.children("ul").length == 1) {
dragged.appendTo(target.children("ul"));
} else {
// depends upon whether I'm dragging from above or from below
if (dragged.prev().is(target)) // dragging from below
dragged.insertBefore(target)
else dragged.insertAfter(target)
}
event.stopPropagation();
},
});
.ui-state-active {
background-color : red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<ul>
<li><span>Test 1</span>
</li>
<li> <span>Test 2</span>
<ul>
<li class="A"><span>Test A</span>
</li>
<li class="B"><span>Test B</span>
</li>
<li class="C"><span>Test C</span>
</li>
</ul>
</li>
<li><span>Test 3</span>
</li>
<li> <span>Test 4</span>
<ul>
<li><span>Test X</span>
</li>
<li><span>Test Y</span>
<ul>
<li><span>F</span>
</li>
<li><span>G</span>
</li>
<li><span>H</span>
</li>
</ul>
</li>
<li><span>Test Z</span>
</li>
</ul>
</li>
</ul>