Разница между $('# tabs a') и $('# tabs'). Find ('a')
У меня есть следующая структура
<ul id="tabs" class="nav nav-tabs">
<li><a href="#aaa" hashval="aaa">AAA</a></li>
<li><a href="#bbb" hashval="bbb">BBB</a></li>
<li><a href="#ccc" hashval="ccc">CCC</a></li>
<li><a href="#ddd" hashval="ddd">DDD</a></li>
</ul>
Теперь я работаю над тегом привязки, следуя коду и работающий нормально.
$('#tabs a[href="#ddd"]').tab('show');
Я использую pycharm, который добавляет предупреждение для строки, говоря "Предисловие с селектором идентификаторов". Когда я нажимаю на него, pycharm изменяется на следующие
$('#tabs').find('a[href="#ddd"]').tab('show');
Оба работают нормально, но я не понимаю разницы.
В чем разница в том или ином конкретном различии между $('#tabs a[href="#ddd"]')
и $('#tabs').find('a[href="#ddd"]')
?
Ответы
Ответ 1
$("#tabs a")
оценивается от справа налево - это собственное направление как механизма Sizzle, так и querySelectorAll
- т.е. сначала он находит все элементы привязки на странице, а затем сужает их до тех, что находятся под #tabs
.
$("#tabs").find("a")
оценивает - более интуитивно - от слева направо, т.е. сначала находит #tabs
, а затем только элементы привязки под ним.
Очевидно, что последнее даст лучшую производительность, но это будет заметно только накопительно; то есть, если вы запускаете тысячи запросов. В противном случае разница незначительна.
Ответ 2
Как указано в "Повысить спецификацию слева направо" :
Небольшое знание механизма селектора jQuerys полезно. Оно работает от последнего селектора, поэтому в старых браузерах запрос, например:
$("p#intro em");
загружает каждый элемент em в массив. Затем он работает над родителями каждый node и отклоняет те, где p # intro не может быть найден. Запрос будут особенно неэффективными, если у вас есть сотни тегов em страница.
В зависимости от вашего документа запрос можно оптимизировать, извлекая сначала - лучший квалифицированный селектор. Затем его можно использовать в качестве стартового точка для дочерних селекторов, например
$("em", $("p#intro")); // or
$("p#intro").find("em");
Но Тест-сценарий говорит, что $("#tabs > a")
будет быстрее
Ответ 3
Второй - намного быстрее.
Причина в том, что селектор jQuery enginge Sizzle, который пересекает выделение от справа до слева, а не наоборот.
Это означает, что селектор
$('#tabs a[href="#ddd"]')
Сначала запрашивает документ DOM для тега, который содержит атрибут href
, установленный в #ddd
. Затем он фильтрует все из них, чтобы получить каждый тег <a>
. Наконец, он пересекает дерево DOM для каждого node, пытаясь найти родителя #tabs
.
Представьте себе сайт с 1.000 тегами с href="#ddd"
, насколько это будет чрезвычайно медленным.
THEN.
Другой вариант pycharm предполагает, что сначала нужно найти элемент #tabs
. Это очень быстро, поскольку jQuery может использовать собственный метод браузера getElementById()
. Имея этот node, он может перемещаться вниз, чтобы найти все теги, которые соответствуют. Делая это, нужно не проверять all tags in the whole DOM-tree
. Только те, которые на самом деле находятся в #tabs
.
Для получения дополнительной информации, пожалуйста, просмотрите эту страницу в документации.
Ответ 4
Эффект тот же: найдите привязки, которые имеют значение #ddd
как href
и являются потомками #tabs
. Разница заключается в том, чтобы достичь этого.
Первое решение находит привязки, а затем проверяет, является ли он потомком #tabs
.
Второе решение находит #tabs
, а затем находит привязки. Конечно, это должно быть быстрее.
Ответ 5
.find()
лучше по сравнению с вашим первым селектором
$('#tabs a[href="#ddd"]').tab('show');
поэтому pycharm изменяет его на селектор с помощью .find()
$('#tabs').find('a[href="#ddd"]').tab('show');
http://vaughnroyko.com/the-real-scoop-on-jquery-find-performance/
Ответ 6
Разница заключается в том, что find() позволяет вам фильтровать по набору элементов на основе выбранного вами выбора, возврата и массива элементов, если этот случай.
$('#tabs').find('a[href="#ddd"]');
И это более конкретный способ поиска элемента, потому что вы говорите "эй, иди в #tabs
и найди мне все a[href="#ddd"]
там", вместо того, чтобы сказать "эй, найди мне всех этих парней $('#tabs a[href="#ddd"]')
во всем коде, который у меня есть."
Ответ 7
Хотя в большинстве случаев производительность является единственной разницей, разница в подходе также может повлиять на результат вашего кода, в зависимости от того, какие селектора вы используете.
Например, $("table").find("tr:even").addClass("even");
добавит класс "четный" к каждой другой строке в каждой отдельной таблице, которая будет возвращена. Итак, если класс "четный" делает текст в строках жирным шрифтом, и у вас есть две таблицы, каждая из которых имеет 3 строки, вы получите следующий результат:
это таблица первая, строка 1
это таблица первая, строка 2
это таблица первая, строка 3
это таблица вторая, строка 1
это таблица вторая, строка 2
это таблица вторая, строка 3
В обоих случаях первая и третья строки каждой таблицы (т.е. "четные" строки... не заставляют меня запускать фильтр JQuery even
, выбирая нечетные строки...) выделены полужирным шрифтом.
С другой стороны, $("table tr:even").addClass("even");
добавит класс "четный" к каждой другой строке во всей группе строк из всех объединенных таблиц.
это таблица первая, строка 1
это таблица первая, строка 2
это таблица первая, строка 3
это таблица вторая, строка 1
это вторая таблица, строка 2
это таблица вторая, строка 3
В этой ситуации первая и третья строки второй таблицы фактически являются 4-й и 6-й строками всей группы элементов <tr>
, поэтому они рассматриваются как "нечетные". Вторая строка второй таблицы, однако, является пятой строкой всей коллекции и, таким образом, рассматривается как "четная" и выделена полужирным.