QuerySelector и querySelectorAll vs getElementsByClassName и getElementById в JavaScript
Я хотел бы знать, в чем разница между querySelector
и querySelectorAll
от getElementsByClassName
и getElementById
?
От эта ссылка Я мог бы собрать, что с querySelector
я могу написать document.querySelector(".myclass")
, чтобы получить элементы с классом myclass
и document.querySelector("#myid")
получить элемент с идентификатором myid
. Но я уже могу сделать это getElementsByClassName
и getElementById
. Какой из них предпочтительнее?
Также я работаю в XPages, где идентификатор динамически генерируется с помощью двоеточия и выглядит как view:_id1:inputText1
. Поэтому, когда я пишу document.querySelector("#view:_id1:inputText1")
, это не работает. Но писать document.getElementById("view:_id1:inputText1")
работает. Любые идеи, почему?
Ответы
Ответ 1
Я хотел бы знать, что именно представляет собой различие между querySelector и querySelectorAll от getElementsByClassName и getElementById?
Синтаксис и поддержка браузера.
querySelector
более полезен, если вы хотите использовать более сложные селектора.
например. Все элементы списка, происходящие из элемента, который является членом класса foo: .foo li
document.querySelector( "# view: _id1: inputText1" ), он не работает. Но работает document.getElementById( "view: _id1: inputText1" ). Любые идеи, почему?
Символ :
имеет особое значение внутри селектора. Вы должны избежать этого. (Символ escape-кнопки селектора имеет особое значение в строке JS, поэтому вам тоже нужно сбежать).
document.querySelector("#view\\:_id1\\:inputText1")
Ответ 2
сбор от Mozilla Документация:
Интерфейс NodeSelector В этой спецификации добавляются два новых метода для любых объектов, реализующих интерфейсы Document, DocumentFragment или Element:
querySelector
Возвращает первый соответствующий элемент Element в поддереве узла. Если соответствующий узел не найден, возвращается null.
querySelectorAll
Возвращает NodeList, содержащий все соответствующие узлы Element в поддереве узла или пустой NodeList, если совпадений не найдено.
а также
Примечание. NodeList, возвращаемый querySelectorAll querySelectorAll()
, не является живым, что означает, что изменения в DOM не отражаются в коллекции. Это отличается от других методов запросов DOM, которые возвращают списки узлов в реальном времени.
Ответ 3
О различиях в результатах между querySelectorAll
и getElementsByClassName
есть важное значение: возвращаемое значение отличается. querySelectorAll
возвращает статическую коллекцию, а getElementsByClassName
возвращает живую коллекцию. Это может привести к путанице, если вы сохраните результаты в переменной для последующего использования:
- Переменная, сгенерированная с помощью
querySelectorAll
, будет содержать элементы, которые выполнили селектор в тот момент, когда метод был вызван.
- Переменная, сгенерированная с помощью
getElementsByClassName
, будет содержать элементы, которые выполнили селектор при его использовании (который может отличаться от момента вызова метода).
Например, обратите внимание, что даже если вы не переназначили переменные aux1
и aux2
, после обновления классов они будут содержать разные значения:
// storing all the elements with class "blue" using the two methods
var aux1 = document.querySelectorAll(".blue");
var aux2 = document.getElementsByClassName("blue");
// write the number of elements in each array (values match)
console.log("Number of elements with querySelectorAll = " + aux1.length);
console.log("Number of elements with getElementsByClassName = " + aux2.length);
// change one element class to "blue"
document.getElementById("div1").className = "blue";
// write the number of elements in each array (values differ)
console.log("Number of elements with querySelectorAll = " + aux1.length);
console.log("Number of elements with getElementsByClassName = " + aux2.length);
.red { color:red; }
.green { color:green; }
.blue { color:blue; }
<div id="div0" class="blue">Blue</div>
<div id="div1" class="red">Red</div>
<div id="div2" class="green">Green</div>
Ответ 4
querySelector
может быть полным CSS (3) -селектором с идентификаторами и классами и псевдоклассами вместе следующим образом:
'#id.class:pseudo'
// or
'tag #id .class .class.class'
с getElementByClassName
вы можете просто определить класс
'class'
с getElementById
вы можете просто определить id
'id'
Ответ 5
Я пришел на эту страницу, чтобы узнать лучший метод для использования с точки зрения производительности - то есть быстрее:
querySelector / querySelectorAll or getElementsByClassName
и я нашел это: https://jsperf.com/getelementsbyclassname-vs-queryselectorall/18
Он запускает тест на примере 2 x выше, плюс его зажимает в тесте для эквивалентного селектора jQuery. мои результаты были следующими:
getElementsByClassName = 1,138,018 operations / sec - <<< clear winner
querySelectorAll = 39,033 operations / sec
jquery select = 381,648 operations / sec
Ответ 6
Для этого ответа я обращаюсь к querySelector
и querySelectorAll
как querySelector * и к getElementById
, getElementsByClassName
, getElementsByTagName
и getElementsByName
как getElement *.
Основные отличия
- querySelector * более гибок, так как вы можете передать ему любой селектор CSS3, а не только простые для id, тега или класса.
- Производительность querySelector * изменяется в зависимости от размера DOM, для которого он вызывается. Чтобы быть точным, вызовы querySelector * выполняются за время O (n), а вызовы getElement * выполняются за время O (1), где n - общее количество всех дочерних элементов элемента или документа, для которых он был вызван. Этот факт кажется наименее известным, поэтому я обдумываю его.
- Вызовы getElement * возвращают прямые ссылки на DOM, тогда как querySelector * внутренне делает копии выбранных элементов перед возвратом ссылок на них. Они называются "живыми" и "статическими" элементами. Это НЕ строго связано с типами, которые они возвращают. Я не знаю, как определить, является ли элемент активным или статическим программно, так как это зависит от того, был ли элемент скопирован в какой-то момент и не является внутренним свойством данных. Изменения в живых элементах применяются немедленно - изменение активного элемента изменяет его непосредственно в DOM, и поэтому следующая строка JS может увидеть это изменение, и оно распространяется на любые другие активные элементы, ссылающиеся на этот элемент немедленно. Изменения в статических элементах записываются обратно в DOM только после завершения выполнения текущего скрипта. Эти дополнительные шаги копирования и записи оказывают небольшое и, как правило, незначительное влияние на производительность.
- Типы возврата этих вызовов различаются.
querySelector
и getElementById
оба возвращают один элемент. querySelectorAll
и getElementsByName
возвращают NodeLists, являясь более новыми функциями, которые были добавлены после того, как HTMLCollection вышел из моды. Старые getElementsByClassName
и getElementsByTagName
возвращают HTMLCollections. Опять же, это по существу не имеет отношения к тому, являются ли элементы живыми или статичными.
Эти понятия обобщены в следующей таблице.
Function | Live? | Type | Time Complexity
querySelector | N | Element | O(n)
querySelectorAll | N | NodeList | O(n)
getElementById | Y | Element | O(1)
getElementsByClassName | Y | HTMLCollection | O(1)
getElementsByTagName | Y | HTMLCollection | O(1)
getElementsByName | Y | NodeList | O(1)
Подробности, советы и примеры
-
HTMLCollections не так массивны, как NodeLists, и не поддерживают .forEach(). Я считаю, что оператор распространения полезен, чтобы обойти это:
[...document.getElementsByClassName("someClass")].forEach()
-
Каждый элемент и глобальный document
имеют доступ ко всем этим функциям, кроме getElementsByName
, который реализован только в document
.
-
Цепочка вызовов getElement * вместо использования querySelector * улучшит производительность, особенно на очень больших DOM. Даже на небольших DOM и/или с очень длинными цепями это обычно быстрее. Однако, если вы не знаете, что вам нужна производительность, читаемость querySelector * должна быть предпочтительной. querySelectorAll
часто сложнее переписать, потому что вы должны выбирать элементы из NodeList или HTMLCollection на каждом шаге. Например, следующий код не работает:
document.getElementsByClassName("someClass").getElementsByTagName("div")
потому что вы можете использовать getElements * только для отдельных элементов, но не для коллекций. Например:
document.querySelector("#someId.someClass div")
может быть написано как:
document.getElementById("someId").getElementsByClassName("someClass")[0].getElementsByTagName("div")[0]
Обратите внимание на использование [0]
для получения только первого элемента коллекции на каждом шаге, который возвращает коллекцию, в результате чего в конце появляется один элемент, как и в querySelector
.
-
Поскольку все элементы имеют доступ как к вызовам querySelector *, так и к getElement *, вы можете создавать цепочки, используя оба вызова, что может быть полезно, если вы хотите повысить производительность, но не можете избежать запроса querySelector, который нельзя записать в терминах вызовов getElement *.,
-
Хотя, как правило, легко определить, можно ли писать селектор, используя только вызовы getElement *, есть один случай, который может быть неочевидным:
document.querySelectorAll(".class1.class2")
можно переписать как
document.getElementsByClassName("class1 class2")
-
Использование getElement * для статического элемента, извлеченного с помощью querySelector *, приведет к тому, что элемент будет действителен по отношению к статическому подмножеству DOM, скопированному с помощью querySelector, но не будет действителен по отношению к полному DOM документа... вот где простое Живая/статическая интерпретация элементов начинает разваливаться. Вам, вероятно, следует избегать ситуаций, когда вам придется беспокоиться об этом, но если вы это сделаете, помните, что querySelector * вызывает элементы копирования, которые они находят, прежде чем возвращать ссылки на них, но getElement * вызывает выборку прямых ссылок без копирования.
-
Ни один API не указывает, какой элемент должен быть выбран первым, если есть несколько совпадений.
-
Поскольку querySelector
выполняет итерацию по DOM до тех пор, пока не найдет совпадение (см. Основное отличие № 2), вышеприведенное также подразумевает, что вы не можете полагаться на положение элемента, который вы ищете в DOM, чтобы гарантировать его быстрое обнаружение - браузер может проходить через DOM назад, вперед, сначала в глубину, в ширину или в противном случае.
Ответ 7
querySelector
и querySelectorAll
являются относительно новыми API, тогда как getElementById
и getElementsByClassName
были с нами намного дольше. Это означает, что то, что вы используете, будет в основном зависеть от того, какие браузеры вам нужно поддерживать.
Что касается :
, он имеет особое значение, поэтому вам нужно избегать его, если вам нужно использовать его как часть имени ID/класса.
Ответ 8
Разница между "querySelector" и "querySelectorAll"
//querySelector returns single element
let listsingle = document.querySelector('li');
console.log(listsingle);
//querySelectorAll returns lit/array of elements
let list = document.querySelectorAll('li');
console.log(list);
//Note : output will be visible in Console
<ul>
<li class="test">ffff</li>
<li class="test">vvvv</li>
<li>dddd</li>
<li class="test">ddff</li>
</ul>
Ответ 9
querySelector
имеет w3c Selector API
getElementBy
имеет API-интерфейс w3c DOM
IMO самое заметное отличие состоит в том, что возвращаемый тип querySelectorAll
является статическим списком узлов, а для getElementsBy
- списком живых узлов. Поэтому цикл в демо 2 никогда не заканчивается, потому что lis
и обновляется во время каждой итерации.
// Demo 1 correct
var ul = document.querySelectorAll('ul')[0],
lis = ul.querySelectorAll("li");
for(var i = 0; i < lis.length ; i++){
ul.appendChild(document.createElement("li"));
}
// Demo 2 wrong
var ul = document.getElementsByTagName('ul')[0],
lis = ul.getElementsByTagName("li");
for(var i = 0; i < lis.length ; i++){
ul.appendChild(document.createElement("li"));
}
Ответ 10
посмотри на это
https://codepen.io/bagdaulet/pen/bzdKjL
getElementById быстрее, чем querySelector на 25%
JQuery является самым медленным
var q = time_my_script(function() {
for (i = 0; i < 1000000; i++) {
var w = document.querySelector('#ll');
}
});
console.log('querySelector: '+q+'ms');
Ответ 11
чтобы сделать это простым
document.querySelectorAll('query')[0] === document.querySelector('query')
Ответ 12
Основное различие между querySelector и getlementbyID (Claassname, Tagname и т.д.) Заключается в том, что если существует более одного элемента, удовлетворяющего условию, то querySelector вернет только один вывод, тогда как getElementBy * вернет все элементы.
Давайте рассмотрим пример, чтобы сделать его более понятным.
<nav id="primary" class="menu">
<a class="link" href="#">For Business</a>
<a class="link" href="#">Become an Instructor</a>
<a class="link" href="#">Mobile Applications</a>
<a class="link" href="#">Support</a>
<a class="link" href="#">Help</a>
</nav>
Ниже код объяснит разницу
**QUERY SELECTOR**
document.querySelector('.link'); // Output : For Business (element)
document.querySelectorAll('.link'); //Out All the element with class link
**GET ELEMENT**
document.getElementsByClassName('link') // Output : will return all the element with a class "link" but whereas in query selector it will return only one element which encounters first.
Inshort, если мы хотим выбрать один элемент, перейти к Queryslector или если мы хотим, чтобы несколько элементов перейти к getElement