2012-01-09 3 views
10

Я работаю с панелью 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> 
+0

возможно: содержит селектор - это решение. http://api.jquery.com/contains-selector/ – ggzone

+0

Знаете ли вы имя класса CSS родителя? –

ответ

17

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

Контрольный показатель: 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... 
+0

Является ли ваш второй вариант быстрее, чем у меня? Я предполагаю, что parentNode означает parent() – jQuerybeast

+0

@ jQuerybeast. Я включил контрольный показатель: http://jsperf.com/parents-method –

+0

Спасибо и за бенчмарк. Довольно многое, что я искал – jQuerybeast

8

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

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

КОММЕНТАРИЙ

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

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

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

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

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

+0

ближайший не считается быстрее. jQuery должен искать ближе, где родители не – jQuerybeast

+0

Да, это была моя мысль. Но я думаю, что здесь есть небольшая жертва в обмен на более четкий, более сжатый код. Если вам нужна чистая скорость, вы можете также полностью пропустить jQuery и вместо этого использовать ['node.parentNode'] (https://developer.mozilla.org/En/DOM/Node.parentNode). – Blazemonger

+0

Спасибо. Хорошо ответил. Выбранный ответ Роба как его то, что я буду использовать, и для теста – jQuerybeast

2

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

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

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

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

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

Я знаю ближайший, но, вероятно, самый медленный из всех, и поскольку приложение становится все больше и больше, это будет боль. Я полагаю, как сказал Роб У., parentNode будет быстрее? – jQuerybeast

+1

@ jQuerybeast Да: [это то, что использует jQuery внутри] (https://github.com/jquery/jquery/blob/master/src/traversing.js#L179). – lonesomeday

+0

Ха! Хороший по ссылке. Учитывая, что вы «не оптимизировали преждевременно», я не уверен, следует ли мне поменять parent() с parentNode или оставить его как есть – jQuerybeast

1

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

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

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