Использование свойств хранилища данных jQuery и свойств расширения - PullRequest
17 голосов
/ 21 июля 2009

Я занимаюсь разработкой кода с использованием jQuery и мне нужно хранить данные, связанные с определенными элементами DOM. Есть множество других вопросов о , как хранить произвольные данные с html-элементом, но меня больше интересует, почему я выбрал бы один вариант над другим.

Скажем ради очень упрощенного аргумента, что я хочу сохранить свойство "lineNumber" с каждой строкой в ​​"интересной" строке.

Вариант 1 заключается в том, чтобы просто установить свойство expando для каждого элемента DOM (надеюсь, я правильно использую термин 'expando'):

$('.interesting-line').each(function(i) { this.lineNumber = i; });

Вариант 2 - использовать функцию data () jQuery для привязки свойства к элементу:

$('.interesting-line').each(function(i) { $(this).data('lineNumber', i); });

Игнорируя любые другие недостатки моего примера кода, есть ли веские причины, по которым вы бы выбрали один способ хранения свойств над другим?

Ответы [ 3 ]

21 голосов
/ 25 января 2011

Использование $.data защитит вас от утечек памяти.

В IE, когда вы присваиваете объект javascript свойству expando в элементе DOM, циклы, пересекающие эту ссылку, не собираются мусором. Если ваш объект javascript содержит ссылку на объект dom, весь цикл будет протекать. Из-за замыканий вполне возможно получить скрытые ссылки на объекты DOM, поэтому вы можете получить утечку, даже не осознавая этого.

Хранилище данных jQuery настроено для предотвращения формирования этих циклов. Если вы используете его, вы не потеряете память таким образом. Ваш пример не пропустит, потому что вы помещаете примитивы (строки) в элемент DOM. Но если вы поместите туда более сложный объект, вы рискуете протечь.

Используйте $.data, чтобы вам не пришлось беспокоиться.

13 голосов
/ 21 июля 2009

Если вы создаете плагин, вы должны использовать $.data. Если вам нужно хранить атрибут часто и редко нужно запрашивать его у DOM, используйте $.data.

Сказав это, для всех моих клиентских приложений я склонен хранить собственные атрибуты DOM на самом элементе DOM, чтобы я мог запросить их позже, используя атрибут [] selector:

var domElement = $('.interesting-line[lineNumber=' + lineNumber + ']').get(0);

Это намного удобнее для чтения, чем повторение упакованного набора, вызывающего .data() для каждого элемента. Часто я взаимодействую с другой сторонней библиотекой, которая работает с элементом DOM, поэтому быстрый и легкий доступ к элементу DOM через этот механизм делает код читабельным.

Это так же просто, как сохранить сопоставление таблицы поиска lineNumbers для элементов, однако метод атрибута expando по сравнению с ним менее подвержен риску утечки памяти, поскольку вы не сохраняете ссылки на элементы DOM, которые необходимо очистить позже.

Обновление через 5 лет Просто прочитайте это после того, как оно получило [вполне заслуженное] отрицательное голосование: пожалуйста, игнорируйте выделенный текст выше. jQuery не запрашивает DOM, основываясь на наборе свойств расширения, и некоторое время не делал этого. Так что используйте $.data. Нет причин загрязнять DOM, если для этого нет практического применения.

2 голосов
/ 21 июля 2009

Использование $.data не изменяет DOM. Вы должны использовать $.data. Если вы создаете плагин, вам следует хранить один объект в $.data со свойствами этого объекта, а не сохранять каждое из этих свойств в виде различных пар ключ / значение в структуре $.data.

...