Какой самый эффективный способ пройти в jQuery? - PullRequest
5 голосов
/ 06 июня 2011

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

Как вы можете видеть из моей разметки ниже - кнопка ЗАКРЫТЬ глубоко вложена в DOM. Когда пользователь нажимает кнопку ЗАКРЫТЬ - мне нужно скрыть () родительский ящик-1. Имейте в виду, у меня может быть до 100 товаров, отображаемых на странице (100 коробок "Box-1") одновременно.

Моя разметка выглядит так:

<div class="box-1">
  <div class="box-2">
    <div class="box-3">...</div> <!-- end box-3 -->

    <div class="box-4">
      <div class="box-5">...</div> <!-- end box-5 -->
        <a class="btn-close" href="#">CLOSE</a>  <!-- this triggers the close event -->
    </div> <!-- end box-4 -->
  </div> <!-- end box-2 -->

  <div class="box-6">
    <div class="box-7">...</div> <!-- end box-7 -->

    <div class="box-8">
      ...
      <div class="box-9">...</div> <!-- end box-9 -->
    </div> <!-- end box-8 -->
  </div> <!-- end box-6 -->
</div> <!-- end box-1 -->

Мой вопрос - как мне лучше (и наиболее эффективно) пройти обратно DOM, чтобы овладеть «коробкой-1» и запустить метод .hide () ... вот мой существующий код.

<script>
$productsResultItems.delegate('.btn-close', 'click', function (e) {
    //box-1
    $(this).parents('div.box-1').hide(); // <-- is this the best way?????
    e.preventDefault();
</script>

Первоначально я пытался это -

$this.parents().find('.hover-box-large').hide();

, который оказался очень медленным в IE7 и IE8.

Я обнаружил, что добавление дополнительных деталей к селектору улучшило производительность почти в 100 раз для IE7, но только в 4 раза быстрее в IE8 :( IE8 по-прежнему требуется около 200 мс, чтобы закрыть родительский контейнер. Где сейчас все другие браузеры (Chrome, Safari) , Firefox и IE7) закрывают контейнер менее чем за 20 мс.

$this.parents('div.hover-box-large').hide();

Но есть ли метод выбора, который еще лучше? Какая-то конкретная причина, почему IE8 слишком плох при таком типе восходящего обхода ??

Ответы [ 4 ]

5 голосов
/ 06 июня 2011

Лучший метод для использования - closest, который находит ближайший элемент-предок, соответствующий селектору:

$this.closest('div.box-1').hide();
3 голосов
/ 06 июня 2011

На самом деле .closest() должно быть быстрее, чем .parents().

В jQuery Docs на .closest() вы можете найти:

.closest ()

  • Начинается с текущего элемента
  • Перемещается вверх по дереву DOM, пока не найдет совпадение для поставляемого селектора
  • Возвращенный объект jQuery содержит ноль или один элемент

.parents ()

  • Начинается с родительского элемента
  • .Дерево DOM к корневому элементу документа, добавляя каждый элемент-предок во временную коллекцию;Затем он фильтрует эту коллекцию на основе селектора, если он указан
  • Возвращенный объект jQuery содержит ноль, один или несколько элементов

Так что в вашем случае, .closest() будет наиболее подходящим, так как вам нужно найти один элемент, ближайшего предка, который соответствует вашему селектору.parents() отфильтрует все возможные элементы-предки, даже если он уже найдет тот, который вам нужен.

1 голос
/ 06 июня 2011

Единственное различие между parent () и closest () состоит в том, что closest () останавливается, когда находит совпадение, поэтому всегда возвращает 0 или 1 элемент.Parents () будет соответствовать всему DOM.

$(this).closest('.box-1').hide();
0 голосов
/ 26 июля 2011

Не так быстро! closest() может быть лучшим, но не всегда! Вот как вы можете узнать это сами. Используйте функции Firebug time () и timeEnd () для фактической регистрации ваших звонков. Затем выберите тот, который подходит для ситуации.

// 59ms
console.time("Parent x 3");
$container = $element.parent().parent().parent();
console.timeEnd("Parent x 3");

// 3ms              
console.time("Closest parent");
$container = $element.closest('.some-class').parent();
console.timeEnd("Closest parent");

// 2ms              
console.time("Parents");
$container = $element.parents('.other-class').eq(1);
console.timeEnd("Parents"); 
...