滚动可拖动项目的内容时禁用jQuery拖动

我通常不会提出这样的问题/答案,但我想我会这样做,因为我已经看过这个问题20多次了,而且没有一个答案确实有效。 简而言之,问题是如果你有可滚动内容( overflow: auto;在可拖动的jQuery项目内的任何地方,当你点击并拖动滚动条时,父可拖动容器随之拖动。所以,我花了一些时间来处理解。

这是一个会出现此问题的html示例:

 
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.

初始化元素可拖动的典型方法是这样的:

 $(".draggable").draggable() 

我建议基于[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(但这不应该是一个大问题):

 
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。 对于解决方案而言,这并不重要,但我不想添加额外的div级别,因为并不是必须要提出重点。

这是jsfiddle 。

[1] – 监听鼠标事件…除了div的溢出:滚动滚动条?

解决方案是绑定到初始化元素的scroll事件,以及任何元素children。 然后,当任何子项调用scroll命令时,找到该元素的所有可拖动父项,并在该元素上设置滚动数据元素。

在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); }); 

对于你的观看/ 涉及的乐趣,我也包括了一个问题的解决方案。

我正在寻找这个问题,并找到了一个更小的解决方案,对我来说非常有效,我想分享它。 我的解决方案是,停止在子/内容上传播“mousedown”事件。 没有mousedown意味着没有拖动;)

 $(".draggable").draggable(); $("#content").mousedown(function(event) { event.stopPropagation(); }); 

这是非常好的解决方案,但它有一个bug。 一旦设置为滚动,则需要第二次拖动才能实际拖动元素。