Parent (), более быстрая альтернатива? - PullRequest
11 голосов
/ 09 января 2012

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

В основном я делаю $(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>

Ответы [ 4 ]

18 голосов
/ 09 января 2012

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

Тест: 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...
9 голосов
/ 09 января 2012

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

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

КОММЕНТАРИЙ

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

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

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

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

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

2 голосов
/ 09 января 2012

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

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

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

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

$(this).closest('div.dashdiv').prop('id');
1 голос
/ 09 января 2012

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

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

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