Я пишу расширение для jQuery, которое добавляет данные к элементам DOM, используя
el.data('lalala', my_data);
, а затем использует эти данные для динамической загрузки элементов.
Каждый раз, когда я получаю новые данные изна сервере мне нужно обновить все элементы, имеющие
el.data('lalala') != null;
Чтобы получить все необходимые элементы, я использую расширение Джеймс Падолси :
$(':data(lalala)').each(...);
Все было замечательно, покаЯ пришел к ситуации, когда мне нужно выполнить этот код 50 раз - это очень медленно !Выполнение на моей странице занимает около 8 секунд с 3640 элементами DOM
var x, t = (new Date).getTime();
for (n=0; n < 50; n++) {
jQuery(':data(lalala)').each(function() {
x++;
});
};
console.log(((new Date).getTime()-t)/1000);
Так как мне не нужен RegExp в качестве параметра селектора :data
, я попытался заменить его на
var x, t = (new Date).getTime();
for (n=0; n < 50; n++) {
jQuery('*').each(function() {
if ($(this).data('lalala'))
x++;
});
};
console.log(((new Date).getTime()-t)/1000);
Этот код быстрее (5 секунд), но я хочу получить больше.
Q Есть ли более быстрый способ получить все элементы с помощью этого ключа данных?
На самом деле, я могу сохранить массив со всеми необходимыми мне элементами, так как я выполняю .data('key')
в моем модуле.Лучше проверять 100 элементов с желаемым .data('lalala')
, чем проверять 3640:)
Таким образом, решение будет похоже на
for (i in elements) {
el = elements[i];
....
Но иногда элементы удаляются со страницы (используя jQuery * 1036).*).Оба решения, описанные выше [$(':data(lalala)')
solution и if ($(this).data('lalala'))
], будут пропускать удаленные элементы (как мне нужно), в то время как решение с массивом будет по-прежнему указывать на удаленный элемент (на самом деле, элемент не будет действительно удален - он будет толькобыть удален из дерева DOM - потому что мой массив все еще будет иметь ссылку).
Я обнаружил, что .remove()
также удаляет данные из узла, поэтому мое решение изменится на
var toRemove = [];
for (vari in elements) {
var el = elements[i];
if ($(el).data('lalala'))
....
else
toRemove.push(i);
};
for (var ii in toRemove)
elements.splice(toRemove[ii], 1); // remove element from array
Это решение в 100 раз быстрее!
Q Будет ли сборщик мусора освобождать память, занятую элементами DOM при удалении из этого массива?
Помните, на элементы ссылалисьВ дереве DOM мы создали новую ссылку в нашем массиве, затем удалили с помощью .remove()
, а затем удалили из массива.
Есть ли лучший способ сделать это?