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 *.

Основные отличия

  1. querySelector * более гибок, так как вы можете передать ему любой селектор CSS3, а не только простые для id, тега или класса.
  2. Производительность querySelector * изменяется в зависимости от размера DOM, для которого он вызывается. Чтобы быть точным, вызовы querySelector * выполняются за время O (n), а вызовы getElement * выполняются за время O (1), где n - общее количество всех дочерних элементов элемента или документа, для которых он был вызван. Этот факт кажется наименее известным, поэтому я обдумываю его.
  3. Вызовы getElement * возвращают прямые ссылки на DOM, тогда как querySelector * внутренне делает копии выбранных элементов перед возвратом ссылок на них. Они называются "живыми" и "статическими" элементами. Это НЕ строго связано с типами, которые они возвращают. Я не знаю, как определить, является ли элемент активным или статическим программно, так как это зависит от того, был ли элемент скопирован в какой-то момент и не является внутренним свойством данных. Изменения в живых элементах применяются немедленно - изменение активного элемента изменяет его непосредственно в DOM, и поэтому следующая строка JS может увидеть это изменение, и оно распространяется на любые другие активные элементы, ссылающиеся на этот элемент немедленно. Изменения в статических элементах записываются обратно в DOM только после завершения выполнения текущего скрипта. Эти дополнительные шаги копирования и записи оказывают небольшое и, как правило, незначительное влияние на производительность.
  4. Типы возврата этих вызовов различаются. 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