开发者

jquery's selectable plugin's very slow

it's slow 开发者_运维知识库when used on huge lists, etc. how make it fast?


jQuery UI selectable takes all the elements of the DOM structure, limit the numbers of elements to those that are in the top. Add a filter:

$("#items").selectable({filter: 'li'}); 

http://forum.jquery.com/topic/major-performance-problems-with-selectable


If you have a huge list, you'll want to disable the expensive autoRefresh option like this:

$(".mySelector").selectable({ autoRefresh: false });

When you want (say on stop) you can refresh yourself, like this:

$(".mySelector").selectable("refresh");


I found that jquery.selectable is very slow in older browsers (like IE7 and 8) because it has to call the .offset() method on each item. I was using it on the cells in a table, so I was able to reduce the number of .offset() calls to one for each row and one for each column (instead of one call for every cell) by making a modified version of the plugin with a modified refresh function. This made the performance acceptable for large tables. The cellPositions array holds the horizontal position for each column.

      this.refresh = function() {
            var cellPositions = [];
            var firstRow = true;
            selecteeRows = $("tr", self.element[0]);
            selecteeRows.each(function() {
                var row = $(this);
                // adding any filters here seems to slow down IE a lot
                // self.options.filter is not used!!
                var selecteeCells = $(row).find("td"); 
                if (firstRow && selecteeCells.length > 0) {
                    for (var i = 0; i < selecteeCells.length; i++) {
                        cellPositions[i] = $(selecteeCells[i]).offset().left;
                    }
                    cellPositions[selecteeCells.length] = cellPositions[selecteeCells.length - 1] + $(selecteeCells).outerWidth(true);
                    firstRow = false;
                }
                if (selecteeCells.length > 0) {
                    var top = $(selecteeCells).first().offset().top;
                    var bottom = top + $(selecteeCells).first().outerHeight();
                    var i = 0;
                    selecteeCells.each(function() {
                        var $this = $(this);
                        first = false;
                        $.data(this, "selectable-item", {
                            element: this,
                            $element: $this,
                            left: cellPositions[i],
                            top: top,
                            right: cellPositions[i + 1],
                            bottom: bottom,
                            startselected: false,
                            selected: $this.hasClass('ui-selected'),
                            selecting: $this.hasClass('ui-selecting'),
                            unselecting: $this.hasClass('ui-unselecting')
                        });
                        i++;
                    });
                }
            });

        };

Edit: Here's a link to the code in github: https://github.com/dfjackson/jquery.ui.selectableTable


Unlike other jquery ui methods, selector is applied even on nested elements. to select only direct ancestors use:

jQuery('#content').selectable({
filter: '>*',
});


I know this is a couple of years too late, but I've been trying to get selectable feeling snappy on a 50x100 table.

I have found that if I create the selectable on the table's container div (with filter:'td') prior to inserting the table content it runs super fast. In firefox it was instantiating in about 1ms (compared to about 100 when creating it on pre-existing content).


Had the same problem with a very large list and ended up handling the hover event and calling .selectable() there for each row. That solved the issue for me.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜