将 jQuery UI Sortable 应用于页面上的数百个元素会导致页面加载非常慢 - 需要如何提高效率的想法

发布于 2024-11-04 17:20:25 字数 2336 浏览 0 评论 0原文

我正在构建一个拖放日历,并发现 jQuery UI 的可排序功能为我想要做的事情提供了最佳的实时性能。

但是,将可排序应用到数月的时间(一次 60 到 180 天,有时更多)会导致页面加载明显滞后,因为我的脚本正在应用所有这些可排序实例。一旦加载就可以正常工作,但我不想有初始延迟。在某些情况下,浏览器甚至尝试终止脚本。

我尝试使日历的第一天可排序,然后使用 jQuery 的 .clone() 复制到所有其他日期,但不幸的是 jQuery 的 .clone() 似乎没有复制 .sortable 的事件。其他事件(例如单击、双击等)可以很好地复制,但不可排序。在网上做了一些研究,我所能找到的只是 jQuery“不支持插件克隆”的声明。

有更好的方法吗?我已经搜索了 stackoverflow、jQuery UI 论坛和 Google,但没有找到任何帮助。

提前致谢, Jamon

编辑:这是一些代码。没什么特别的。

    function sortableStop(event, ui) {
              // Saves to the DB here. Code removed - not relevant
    }

    $(".milestone-day").bind("dblclick", function(ev) {
      // Allows adding milestones. Code removed - not relevant
    }).sortable({
        handle: '.handle',
        connectWith: '.milestone-day',
        items: '.milestone',
        stop: sortableStop
    });

标记如下所示:

<table>
  <tbody>
    <tr>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
    </tr>
    <tr>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
    </tr>
    ...
  </tbody>
</table>

里程碑是通过 ajax 加载到其正确的里程碑日 ul 中的 li 元素。

编辑2:发布工作演示:

http://www.clearsightstudio。 com/demos/calendar-load/

编辑 3:演示消失了。对不起。

请注意,打开页面时会有延迟。与我的实际应用程序中的演示相比,发生的事情要多得多,因此延迟更加明显。

I'm building a drag and drop calendar and have found that jQuery UI's sortable offers the best live performance for what I'm trying to do.

However, applying sortable to many months worth of days (60 to 180 days at a time -- sometimes more) results in a noticeable lag upon page load as my script is applying all those sortable instances. It works fine once it's loaded, but I'd rather not have the initial lag. In some cases the browser even tries to kill the script.

I tried making the first day of the calendar sortable and then using jQuery's .clone() to copy to all the other days, but unfortunately jQuery's .clone() doesn't appear to copy .sortable's events. Other events (such as click, double click, etc) get copied fine, but not sortable. Doing some research online, all I could find was the statement that jQuery "doesn't support cloning of plugins."

Is there a better way to do this? I've scoured stackoverflow, jQuery UI's forums, and Google in general, and have found nothing of help.

Thanks in advance,
Jamon

EDIT: Here is some code. Nothing too special.

    function sortableStop(event, ui) {
              // Saves to the DB here. Code removed - not relevant
    }

    $(".milestone-day").bind("dblclick", function(ev) {
      // Allows adding milestones. Code removed - not relevant
    }).sortable({
        handle: '.handle',
        connectWith: '.milestone-day',
        items: '.milestone',
        stop: sortableStop
    });

The markup looks like this:

<table>
  <tbody>
    <tr>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
    </tr>
    <tr>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
      <td><ul class="milestone-day"></ul></td>
    </tr>
    ...
  </tbody>
</table>

Milestones are li elements loaded into their proper milestone-day uls via ajax.

EDIT 2: Working demo posted:

http://www.clearsightstudio.com/demos/calendar-load/

EDIT 3: Demo is gone. Sorry.

Note that there's a lag when you open the page. There's a lot more going on than on that demo in my actual app, so the lag is even more noticeable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

允世 2024-11-11 17:20:25

在调用 sortable() 之后调用 connectWith,例如:

$('.whatever').sortable().sortable( "option", "connectWith", '.whatever' );

出于某种原因,它在我的场景中提高了很多性能(数千个元素)

call the connectWith after call the sortable(), example:

$('.whatever').sortable().sortable( "option", "connectWith", '.whatever' );

for some reason it improved the performance a LOT in my scenario (thousands of elements)

风铃鹿 2024-11-11 17:20:25

尽量不要在加载时绑定所有元素,这样做

<script type="text/javascript">
            jQuery(".milestone").live("mouseenter", function(){
                function sortableStop(event, ui) {
                    alert("Sortable stop fired!");
                }

                $($(this).parent()).bind("dblclick", function() {
                    alert("Double-click fired!");
                }).sortable({
                    connectWith: '.milestone-day',
                    items: '.milestone',
                    stop: sortableStop
                });
            });
        </script>

会提高性能

演示: http://jsfiddle.net/P27qv /

try not to bind all the elements onload do something like this

<script type="text/javascript">
            jQuery(".milestone").live("mouseenter", function(){
                function sortableStop(event, ui) {
                    alert("Sortable stop fired!");
                }

                $($(this).parent()).bind("dblclick", function() {
                    alert("Double-click fired!");
                }).sortable({
                    connectWith: '.milestone-day',
                    items: '.milestone',
                    stop: sortableStop
                });
            });
        </script>

this will improve the performance

Demo: http://jsfiddle.net/P27qv/

梦归所梦 2024-11-11 17:20:25

我遇到了类似的问题,有数百张图像需要可拖动。初始化花费了太多时间

我能够通过 mouseenter 上的延迟实例化来解决它,它效果很好,并且用户体验没有改变

在此处查看更多信息 https://stackoverflow.com/a/20399896/287455

I had a similar problem with hundreds of images that needed to be draggable. and initialization just took too much time

I was able to solve it by lazy instantiation upon mouseenter, it works great, and the user experience is not changed

See more info here https://stackoverflow.com/a/20399896/287455

内心旳酸楚 2024-11-11 17:20:25

移动代码以将所有控件绑定到页面加载事件之外。
它不会更快,但对用户来说会显得更快。
您还可以更改代码和标记,以便在加载时禁用各个项目
绑定事件后,它们就会被启用。这将防止快速抽搐
用户点击它们并想知道为什么没有发生任何事情。

Move your code to bind all the controls out of the page load event.
It won't be any faster but it will appear faster to the user.
You might also change the code and markup so the individual items are disabled on load
and after their events are bound they're enabled. This will prevent fast twitch
users from clicking on them and wondering why nothing happened.

森林迷了鹿 2024-11-11 17:20:25

如果我在调用 .sortable() 之前隐藏可排序项,我可以使其速度更快。但是,它只在 iPad Safari 上产生了巨大的变化。对于其他浏览器,情况几乎相同。

示例代码:

$(".milestone-day").hide()

$(".milestone-day").sortable({
    handle: '.handle',
    connectWith: '.milestone-day',
    items: '.milestone',
    stop: sortableStop
});

$(".milestone-day").show()

I was able to make it a lot faster if I hide the sortables before I call .sortable(). But, it only made a huge difference on the iPad Safari. For other browsers, it was pretty much the same.

Example code:

$(".milestone-day").hide()

$(".milestone-day").sortable({
    handle: '.handle',
    connectWith: '.milestone-day',
    items: '.milestone',
    stop: sortableStop
});

$(".milestone-day").show()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文