Родитель(), более быстрая альтернатива?

Я работаю с панелью divs, и каждый div имеет дерево, с которым расположены кнопки. Каждый раз, когда я должен знать, какой id этого div, я использую parent() alot.

В основном я делаю $(this).parent().parent().parent(), чтобы найти идентификатор div, чтобы я мог установить для него переменные. Приложение основано на идентификаторе каждого div.

Рассматривать медленное использование parent() до 3 раз, но в значительной степени для каждой функции?

Есть ли другая альтернатива?

Я ищу что-то вроде эталонных тестов, которые показывают, что быстрее.

Вот пример дерева:

<div id="6179827893" class="dashdiv">
   <div class="buttons">
     <li><a href="#" class="btn1">Button 1</a></li>
     <li><a href="#" class="btn2">Button 2</a></li>
     <li><a href="#" class="btn3">Button 3</a></li>
     <li><a href="#" class="btn4">Button 4</a></li>
     <li><a href="#" class="btn5">Button 5</a></li>
     <li><a href="#" class="btn6">Button 6</a></li>
   </div>
   <div class="dashcontent">

    ....

   </div>
</div>

Ответ 1

У вас есть несколько вариантов для достижения того же эффекта.

Контрольный показатель: http://jsperf.com/parents-method. Согласно этому эталону, мой метод примерно в 100 раз быстрее, чем ваш метод.

Method (see below) : Operations per second (higher is better)
parentNode3x       : 4447k
$(parentNode3x)    :  204K
$().closest        :   35k
$().parents        :    9k
$().parent()3x     :   44k

// Likely the fastest way, because no overhead of jQuery is involved.
var id = this.parentNode.parentNode.parentNode.id;

// Alternative methods to select the 3rd parent:
$(this.parentNode.parentNode.parentNode) // Native DOM, wrapped in jQuery

// Slowpokes
$(this).closest('.dashdiv')              // Hmm.
$(this).parents('.dashdiv:first')        // Hmm...

Ответ 2

Вам может быть лучше использовать .closest(), например: $(this).closest('.dashdiv')

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

Комментарий

Если вам нужна чистая скорость, вы можете также полностью пропустить jQuery и вместо этого использовать node.parentNode. Но это приводит к ничтожным проблемам подсчета циклов, и я думаю, что это академический.

Если вы пишете высокопроизводительный код для крупного производства, например, коммерческую поисковую систему или поставщик веб-почты, то подсчет циклов важен, потому что любая небольшая оптимизация умножается тысячами раз. При всем моем уважении, я сомневаюсь, что вы пишете такой код.

Если вы пишете то, что может пострадать несколько человек за раз, в лучшем случае, небольшие оптимизации - это интеллектуальное упражнение, которое не повлияет на результаты каким-либо заметным образом. Вам нужно будет повысить эффективность кода на сотни миллисекунд, прежде чем любой пользователь даже начнет замечать, и этот код не собирается этого делать.

Вместо этого гораздо важнее подумать о следующем разработчике, который будет смотреть на ваш код. Для этого разработчика важно иметь четкий, хорошо написанный код, который немедленно сообщает, что он делает. Глазуристые цепочки таких методов, как parent().parent().parent(), могут скрывать и путать других разработчиков, не говоря уже о node.parentNode.parentNode.parentNode

- вот почему .closest() был создан в первую очередь. Он ясен, краток и не заметно эффективнее, чем цепи, которые он заменяет. 999 раз из тысячи, это то, как вы должны идти.

Ответ 3

Во-первых, не оптимизируйте преждевременно. Если это не вызовет проблемы (и тщательно протестируйте все средства на разных платформах), не беспокойтесь об этом.

Существует возможная оптимизация: используйте собственные свойства DOM:

var id = this.parentNode.parentNode.parentNode.id;

Обратите внимание, что самый лучший способ jQuery для этого (который будет медленнее, но это может быть не проблема) с closest:

$(this).closest('div.dashdiv').prop('id');

Ответ 4

Если обработчики в настоящее время находятся в элементах <a>, поместите их вместо элементов .dashdiv.

Тогда вы можете сделать this.id, если e.target был элементом <a>.

$('.dashdiv').click(function(e) {
    if( e.target.nodeName.toLowerCase() === 'a' ) {
        alert( this.id );
    }
});