在jQuery UI中触发鼠标拖动

3
使用jQuery 1.2.x和jQuery UI 1.5.x,可以通过以下方式手动触发拖动:
jQuery("#myDiv").mousedown(function(ev) {
target = jQuery(ev.target);
if (target.hasClass("drag-me")) {
    target.draggable({
        helper: "clone",
        start: function()
        {
            console.log("drag start");
        },
        stop: function()
        {
            jQuery(this).draggable("destroy");
        }
    }).trigger("mousedown.draggable", [ev]);
} });

它适用于以下HTML:

<div id="myDiv">
<div class="drag-me"></div>
<div class="drag-me"></div>
<div class="drag-me"></div>
<div class="drag-me"></div>
<div class="drag-me"></div>
<div class="drag-me"></div>
<div class="drag-me"></div>
</div>

这是一种方便的方法,可以将拖动应用于容器内动态更改其子元素的情况。我喜欢称之为“拖动委托”。

然而,在jQuery 1.3.x和jQuery 1.6+发布后,上面的脚本停止工作。使用jQuery 1.3.2和jQuery UI 1.7.1会返回一个错误“too much recursion”。

如何手动触发拖动?有什么建议吗?

5个回答

12

以上的回答看起来过于复杂。

$('.nonDraggableObjectWhichTriggersDrag').mousedown(function(e) {
   $('.draggableObject').trigger(e);
});

3

事实证明,这比你想象的要简单得多。查看.trigger()方法的文档,没有提到除了事件类型的字符串表示外,还可以提供原始事件作为参数。

因此,可以通过以下方式更有效地实现委托拖动:

$("ul#dynamiclist").delegate("li", "mousedown", function(event) {
    $(this).draggable({
            helper: "clone",
            cursorAt: { left: 5, top: -5 },
            cursor: "move",
            stop: function() {
                    $(this).draggable("destroy");
            }
    }); });

理想的解决方案是UI库本身能够原生地为动态元素执行此类委托...

请注意,这适用于jQuery 1.4.2和jQuery UI 1.7.2。


3

如果你没有使用jQuery 1.4(因此没有delegate()方法),有另一种解决方案。

为了防止递归发生,你需要在所有元素的mousedown事件上调用stopPropagate()方法:

$('drag-me').mousedown(function(ev){
  ev.stopPropagation();
});

同时将您的代码更改为以下方式(请注意底部的stopPropagation()调用):
jQuery("#myDiv").mousedown(function(ev) {
target = jQuery(ev.target);
if (target.hasClass("drag-me")) {
        target.draggable({
                helper: "clone",
                start: function()
                {
                        console.log("drag start");
                },
                stop: function()
                {
                        jQuery(this).draggable("destroy");
                }
        }).trigger("mousedown.draggable", [ev]);
        ev.stopPropagation()
    }
});

这应该可以解决您无休止的递归问题。(至少在我类似的情况下是有效的)

1
如果您可以发布一个完整的代码示例(包括具有非工作版本的HTML和相关脚本标签),我可以帮助找出问题在哪里,并/或验证问题....
但是,我不确定您是否想将1个对象数组[ev]作为触发器调用的第二个参数传递。 文档说:“最后,您可以传递一个带有数据的文本对象。它将被复制到真正的jQuery.Event对象中。请注意,在这种情况下,您必须指定类型属性。”
您能够验证它之前是否按照您编写的方式(应该)工作,并/或可能粘贴一些代码或URL到相关页面吗?我很乐意再看一遍。
希望能帮到您。:)
编辑:再次查看它。它正在按照您要求的方式执行。在mousedown事件上,您做了一些事情,然后以触发另一个mousedown事件结束,该事件将执行一些操作,然后引起另一个mousedown事件等等...您已经创建了无限循环。
为什么不在页面加载时就使相关的div可拖动,而不是在第一次单击它们时才这样做?这样不是可以避免这个问题吗?
另外,请查看此帖子,我很想看到一些曾经有效的代码。按照现有的写法,我不确定代码如何模拟完整的“拖动”事件——由mousedown、mousemove和mouseup事件组成。让我知道。谢谢!

我已经添加了HTML。正如我在问题中提到的,它在早期版本的jQuery和jQuery UI(分别为1.2.6和1.5.2)中起作用。我在博客文章中写了这个主题(http://neilcraig.blogspot.com/2008/12/how-to-trigger-jquery-ui-dragging.html)。它需要对jQuery UI源代码进行一些小修复,但确实有效。我尝试使用.trigger(ev)、.trigger("mousedown")以及.trigger("mousedown.draggable")来触发mousedown事件,但是都没有成功。感谢您的帮助。 - NeilC

0

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