Reputation: 71
it's slow when used on huge lists, etc. how make it fast?
Upvotes: 7
Views: 3363
Reputation: 19
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.
Upvotes: 0
Reputation: 630369
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");
Upvotes: 11
Reputation: 2207
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
Upvotes: 4
Reputation: 1673
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).
Upvotes: 0
Reputation: 161
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
Upvotes: 16
Reputation: 123
Unlike other jquery ui methods, selector is applied even on nested elements. to select only direct ancestors use:
jQuery('#content').selectable({
filter: '>*',
});
Upvotes: 2