jQuery使用实时事件进行拖放

41

我有一个长列表的应用程序,其内容经常变化,我需要该列表中的项目具有可拖动功能。

我一直在使用jQuery UI draggable插件,但是将其添加到400多个列表项速度较慢,并且每次添加新的列表项时都必须重新添加。

是否有人知道类似于jQuery UI拖放插件的插件,它使用jQuery 1.3的.live()事件?这将解决这两个问题。


if (!jQuery(this).data("init")) { jQuery(this).data("init", true);} 的作用是什么? - user593838
10个回答

45

Wojtek的解决方案对我完美地起作用了,我稍微改动了一下,使其扩展了jQuery...

(function ($) {
   $.fn.liveDraggable = function (opts) {
      this.live("mouseover", function() {
         if (!$(this).data("init")) {
            $(this).data("init", true).draggable(opts);
         }
      });
      return this;
   };
}(jQuery));

现在不再像这样调用:

$(selector).draggable({opts});

只需使用:

$(selector).liveDraggable({opts})

1
你需要在加载jQuery之后,在代码中使用它之前声明它。你遇到了什么错误? - stldoug
顺便说一下,这是不正确的,当你设置可拖动时,你忘记移除mouseover处理程序了。我会相应地更正fn.liveDraggable。 - Morg.
在尝试解决类似问题时,我也刚刚发现了这个。非常好的解决方案! - Phil
2
比将数据存储在元素中更好的方法是依赖于.ui-draggable CSS类的存在吗?我认为这更轻巧。 - mexique1
3
现今应使用 this.on('mouseover', selector, ...) 替代 this.live('mouseover', ...) - Dehalion
显示剩余2条评论

21

这是我完美运行的代码示例

$('.gadgets-column').live('mouseover',function(){
    $(this).draggable();
});

3
这是一个简单的解决方案,但每次将鼠标悬停在其中一个类为“gadgets-column”的DOM元素上时,都会对所有这样的元素执行可拖动操作... - Michal B.
@MichalB。不,这不是jQuery的工作方式,$(this)指的是鼠标悬停的项目,甚至可以比在之前设置draggable()更轻(即使你鼠标悬停,可拖动逻辑也不会被激活)。 - Morg.
2
@Morg:我同意你所说的一切,只是你没有理解我的意思。每次悬停在具有类gadgets-column的元素上时,代码将执行。代码是$(this).draggable();,这不是你想要每次悬停时都执行的内容。 - Michal B.
非常容易,这是最简单的解决方案。恭喜! - Yises

10
你可以创建一个类似于这样的包装函数:

function liveDraggable(selector, options){
  jQuery(selector).live("mouseover",function(){
    if (!jQuery(this).data("init")) {
      jQuery(this).data("init", true);
      jQuery(this).draggable(options);
    }
  });
}

(我在使用Prototype和jQuery - 这就是为什么我把jQuery()放在$()的位置)

现在,不要使用$(selector).draggable({opts}),而是使用liveDraggable(selector, {opts})。


7

Stldoug 的代码对我很有效,但是没有必要在每次 mouseover 事件中检查元素的 .data("init")。同时,最好使用 "mousemove",因为如果你的鼠标已经悬停在元素上时 .live 函数启动时,"mouseover" 并不总是会触发。

(function ($) {
    $.fn.liveDraggable = function (opts) {
        this.live("mousemove", function() {
            $(this).draggable(opts);
        });
    };
}(jQuery));

以下是使用方法:

这里是使用方法:

$('.thing:not(.ui-draggable)').liveDraggable();

技巧在于在您的选择器中添加“:not(.ui-draggable)”。由于当元素可拖动时,jQuery会自动将“ui-draggable”类添加到元素中,因此.live函数将不再针对它进行目标定位。换句话说,它只触发一次,而不像其他解决方案一样在移动内容时反复触发。
理想情况下,您可以只是.unbind “mousemove”,但不幸的是,这在.live中无法工作。

2
是的,绝对更清晰。你觉得将“ui-draggable”的检查移动到插件函数内部怎么样?就像这样:“if(!this.hasClass('ui-draggable')){...}"? - stldoug
你可以使用delegate代替。在那里,你可以指定一个额外的selector。 - Luke

4

将@john和@jasimmk的最佳答案结合起来:

使用.live

$('li:not(.ui-draggable)').live('mouseover',function(){
    $(this).draggable(); // Only called once per li
});

.live已经被弃用,更好的选择是使用.on

$('ul').on('mouseover', 'li:not(.ui-draggable)', function(){
    $(this).draggable();  // Only called once per li
});

正如 @john 所解释的那样,.ui-draggable 自动添加到可拖动方法中,因此通过使用选择器排除该类,您可以确保在每个元素上只调用一次 draggable()。而使用 .on 可以缩小选择器的范围,提高性能。


1
一个例子:
土耳其:
<div id="diyalogKutusu">
    <div id="diyalog-baslik">..baslik..</div>
    <div id="icerik">..icerik..</div>
</div>

$(document).on("mouseover", "#diyalogKutusu", function() {
    $(this).draggable({ handle: '#diyalog-baslik' });
});

English:

<div id="dialogBox">
    <div id="dialogBox-title">..title..</div>
    <div id="content">..content..</div>
</div>

$(document).on("mouseover", "#dialogBox", function() {
    $(this).draggable({ handle: '#dialogBox-title' });
});

注意:您可以使用on()代替live()delegateon()比其他方法具有更好的性能。

1
$("html divs to drag").appendTo("#layoutDiv").draggable(options);

JSFiddle

的英译中,保留了HTML格式,不做解释。

0

另一种选择是将mouseover处理程序与可移除类混合使用,如下所示:

$('.outer-container').on('mouseover', '.my-draggable.drag-unbound', function(e) {
  $(this).draggable().removeClass('drag-unbound');
});

这很简单,解决了其他答案在鼠标悬停时反复重新绑定的一些问题。


0
一个老问题。但是threedubmedia有拖放插件,支持实时(自v 1.7以来被称为“on”)。 http://threedubmedia.com/code/event/drop 我没有太多使用它,所以无法说明它的性能等,但看起来还不错。

0

一个已更新的版本,不再使用已被弃用的 live:

function liveDraggable(selector, options) {
    $(document).on('mouseover', selector, function () {
        if (!$(this).data("init")) {
            $(this).data("init", true);
            $(this).draggable(options);
        }
    });
}

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