jquery's selectable plugin's very slow
Asked Answered
T

6

7

it's slow when used on huge lists, etc. how make it fast?

Tameshatamez answered 6/12, 2010 at 10:6 Comment(0)
P
16

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

Planck answered 15/11, 2011 at 14:57 Comment(0)
S
11

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");
Swathe answered 6/12, 2010 at 10:24 Comment(0)
D
4

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

Dina answered 19/12, 2011 at 21:41 Comment(0)
S
2

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

jQuery('#content').selectable({
filter: '>*',
});
Striation answered 8/8, 2011 at 18:20 Comment(0)
N
0

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

Negativism answered 9/6, 2012 at 0:13 Comment(0)
D
0

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.

Dolan answered 22/12, 2021 at 12:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.