我通常不会提出这样的问题/答案,但我想我会这样做,因为我已经看过这个问题20多次了,而且没有一个答案确实有效。简而言之,问题是如果你在可拖动的jQuery项目中的任何地方都有可滚动内容(overflow: auto;
,当你点击并拖动滚动条时,父拖动容器就会随之拖动。所以,我花了一些时间来处理解决方案。
以下是一些会出现此问题的html示例:
<div class="draggable" style="width:100px;height:100px;">
<div id="content" style="width:80px;height:80px;overflow:auto;">
Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit.
</div>
</div>
将元素初始化为可拖动的典型方法是这样的:
$(".draggable").draggable()
答案 0 :(得分:6)
我建议基于[1]和PriorityMark提供的解决方案的混合解决方案。这个解决方案更可靠,我认为它也更有效率。
$(".draggable").draggable({
start: function(event) {
var content = $(this).children('.content');
// if we're scrolling, don't start and cancel drag
if (event.originalEvent.pageX-content.offset().left > content.innerWidth())
{
console.log('should-cancel');
$(this).trigger("mouseup");
return false;
}
}
});
为此,我稍微调整了示例DOM(但这不应该是一个大问题):
<div class="draggable" style="width:100px;height:100px;overflow:auto;">
<div class="content" style="width:80px;height:80px;">
Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit.
</div>
</div>
请注意,此处 draggable div具有溢出,而不是内容 div。对于解决方案而言,这并不重要,但我不想添加额外的div级别,因为并不是必须提出这一点。
这是jsfiddle。
[1] - listen for mouse events … except a div's overflow:scroll scrollbar?
答案 1 :(得分:5)
解决方案是绑定初始化元素的scroll事件,以及任何元素children。然后,当任何一个孩子调用一个滚动命令时,找到该元素的所有可拖动父元素,并在该元素上设置一个滚动的数据元素。
在jQuery UI的当前版本(1.8.16)下,当您在滚动条上进行鼠标操作时,启动事件始终会启动,并在树上向上运行,因此此解决方案在我的测试中运行良好。
$(".draggable").draggable({
start: function() {
// if we're scrolling, don't start and cancel drag
if ($(this).data("scrolled")) {
$(this).data("scrolled", false).trigger("mouseup");
return false;
}
}
}).find("*").andSelf().scroll(function() {
// bind to the scroll event on current elements, and all children.
// we have to bind to all of them, because scroll doesn't propagate.
//set a scrolled data variable for any parents that are draggable, so they don't drag on scroll.
$(this).parents(".ui-draggable").data("scrolled", true);
});
对于你的观看/涉及的乐趣,我也包括jsfiddle的问题。
答案 2 :(得分:1)
我正在寻找这个问题并找到了一个更小的解决方案,对我来说非常合适,我想分享它。 我的解决方案是,停止在子/内容上传播“mousedown”事件。 没有mousedown意味着没有拖动;)
$(".draggable").draggable();
$("#content").mousedown(function(event) {
event.stopPropagation();
});
答案 3 :(得分:0)
这是非常好的解决方案,但它有一个错误。 一旦设置为滚动,则需要第二次拖动才能实际拖动元素。