【问题标题】:jQuery Drag And Drop Using Live Events使用实时事件的 jQuery 拖放
【发布时间】:2010-12-20 18:49:39
【问题描述】:

我有一个应用程序,其中包含一个经常更改的长列表,我需要该列表中的项目是可拖动的。

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

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

【问题讨论】:

  • if (!jQuery(this).data("init")) { jQuery(this).data("init", true);} 是做什么的?

标签: jquery jquery-ui drag-and-drop draggable livequery


【解决方案1】:

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

【讨论】:

  • 这完全破坏了我的 js。你需要把它放在某个地方来扩展 JQuery 功能吗?
  • 您需要在加载 jQuery 之后以及在代码中使用它之前声明它。你遇到了什么错误?
  • 您忘记返回要链接的元素
  • 比在元素中存储数据更好,为什么不依赖 .ui-draggable CSS 类的存在呢?我觉得这个比较轻
  • 现在你应该使用this.on('mouseover', selector, ...) 而不是this.live('mouseover', ...)
【解决方案2】:

这是一个非常适合我的代码示例

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

【讨论】:

  • 这是一个简单的解决方案,但在所有带有 gadgets-column 类的 DOM 元素上执行可拖动每次您将其中一个悬停...
  • @MichalB。不,这不是 jQuery 的工作方式,$(this) 指的是被鼠标悬停的项目,这甚至比之前设置的 draggable() 更轻(即,在鼠标悬停之前,可拖动逻辑不会处于活动状态)。
  • @Morg:我同意你所说的,你只是不明白我的意思。每次您悬停具有gadgets-column 类的元素时,代码都会执行。代码是$(this).draggable();,这不是您每次悬停时都希望执行的代码。
  • 难以置信的简单,它是最简单的解决方案。恭喜
【解决方案3】:

你可以像这样制作包装函数:

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

(我在 jQuery 中使用原型 - 这就是我放置 jQuery() 而不是 $() 的原因)

现在代替 $(selector).draggable({opts}) 使用 liveDraggable(selector, {opts})

【讨论】:

    【解决方案4】:

    Stldoug 的代码对我有用,但没有必要在每个鼠标悬停事件上继续检查元素的 .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 函数将不再以它为目标。换句话说,它只触发一次,不像其他解决方案在您移动东西时反复触发。

    理想情况下,您可以直接取消绑定“mousemove”,但不幸的是,这不适用于 .live。

    【讨论】:

    • 是的,绝对干净。您如何看待在插件函数中移动“ui-draggable”检查...类似于“if(!this.hasClass('ui-draggable')){...}”?
    • 你不能使用委托代替。在那里你可以指定一个额外的选择器。
    【解决方案5】:

    结合来自@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 会缩小选择器的范围,提高性能。

    【讨论】:

      【解决方案6】:

      一个例子:

      土耳其语:

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

      英语:

      <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() 的性能比其他的好

      【讨论】:

        【解决方案7】:
        $("html divs to drag").appendTo("#layoutDiv").draggable(options);
        

        JSFiddle

        【讨论】:

          【解决方案8】:

          一个老问题。但是threedubmedia 具有实时(从v 1.7 开始称为“on”)支持的拖放插件。 http://threedubmedia.com/code/event/drop 没有使用太多,所以我无法解释它的性能等,但看起来很合理。

          【讨论】:

            【解决方案9】:

            另一种选择是将鼠标悬停处理程序与可移动类混合使用,如下所示:

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

            它相当简单,解决了其他答案在鼠标悬停时一遍又一遍地重新绑定的一些问题。

            【讨论】:

              【解决方案10】:

              不推荐使用的更新版本

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-12-18
                • 2011-09-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多