Что возвращают querySelectorAll, getElementsByClassName и другие методы getElementsBy*?
Делать getElementsByClassName
(и аналогичные функции, такие как getElementsByTagName
а также querySelectorAll
) работают так же, как getElementById
или они возвращают массив элементов?
Я спрашиваю, потому что я пытаюсь изменить стиль всех элементов, используя getElementsByClassName
, Увидеть ниже.
//doesn't work
document.getElementsByClassName('myElement').style.size = '100px';
//works
document.getElementById('myIdElement').style.size = '100px';
14 ответов
Ваш getElementById()
код работает, так как идентификаторы должны быть уникальными и, таким образом, функция всегда возвращает ровно один элемент (или null
если ничего не было найдено).
Тем не мение, getElementsByClassName()
, querySelectorAll()
, и другие getElementsBy*
методы возвращают массив элементов в виде массива. Итерируйте его, как если бы вы использовали реальный массив:
var elems = document.getElementsByClassName('myElement');
for(var i = 0; i < elems.length; i++) {
elems[i].style.size = '100px';
}
Если вы предпочитаете что-то более короткое, подумайте об использовании jQuery:
$('.myElement').css('size', '100px');
Вы используете массив как объект, разница между getElementbyId
а также getElementsByClassName
в том, что:
getElementbyId
вернет вам объект.getElementsByClassName
вернет вам массив.
getElementsByClassName
getElementsByClassName(classNames)
Метод принимает строку, содержащую неупорядоченный набор уникальных разделенных пробелами токенов, представляющих классы. При вызове метод должен возвращать живойNodeList
объект, содержащий все элементы в документе, которые имеют все классы, указанные в этом аргументе, получив классы, разбив строку на пробелы. Если в аргументе не указаны токены, метод должен вернуть пустой NodeList.
https://www.w3.org/TR/2008/WD-html5-20080610/dom.html
getElementById
Метод getElementById() обращается к первому элементу с указанным идентификатором.
http://www.w3schools.com/jsref/met_doc_getelementbyid.asp
в вашем коде строки:
1- document.getElementsByClassName ('myElement'). Style.size = '100px';
не будет работать, как ожидалось, потому что getElementByClassName
вернет массив, и массив не будет иметь style
собственность, ты получишь доступ к каждому element
повторяя их.
Вот почему функция getElementById
работал для вас, эта функция вернет вам прямой объект, и поэтому вы сможете получить доступ к style
имущество.
ES6 обеспечивает Array.from()
метод, который создает новый экземпляр Array из массива или итеративного объекта.
let boxes = document.getElementsByClassName('box');
Array.from(boxes).forEach(v => v.style.background = 'green');
console.log(Array.from(boxes));
.box {
width: 50px;
height: 50px;
margin: 5px;
background: blue;
display: inline-block;
}
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
Как вы можете видеть внутри фрагмента кода, после использования Array.from()
Функция, которую вы затем можете манипулировать над каждым элементом.
То же решение с использованием jQuery
,
$('.box').css({'background':'green'});
.box {
width: 50px;
height: 50px;
margin: 5px;
background: blue;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
Следующее описание взято с этой страницы:
Метод getElementsByClassName() возвращает коллекцию всех элементов в документе с указанным именем класса в виде объекта NodeList.
Объект NodeList представляет коллекцию узлов. Доступ к узлам осуществляется по номерам индексов. Индекс начинается с 0.
Совет: Вы можете использовать свойство length объекта NodeList, чтобы определить количество элементов с указанным именем класса, затем вы можете просмотреть все элементы и извлечь нужную информацию.
Итак, в качестве параметра getElementsByClassName
примет имя класса.
Если это ваше тело HTML:
<div id="first" class="menuItem"></div>
<div id="second" class="menuItem"></div>
<div id="third" class="menuItem"></div>
<div id="footer"></div>
затем var menuItems = document.getElementsByClassName('menuItem')
вернет коллекцию (не массив) из 3 верхних <div>
s, так как они соответствуют заданному имени класса.
Затем вы можете перебрать эти узлы (<div>
в данном случае) коллекция с:
for (var menuItemIndex = 0 ; menuItems.length ; menuItemIndex ++) {
var currentMenuItem = menuItems[menuItemIndex];
// do stuff with currentMenuItem as a node.
}
Пожалуйста, обратитесь к этому сообщению для получения дополнительной информации о различиях между элементами и узлами.
Другими словами
document.querySelector()
выбирает только первый элемент указанного селектора. Так что это не выплевывает массив, это одно значение. Похожий наdocument.getElementById()
который выбирает только ID-элементы, так как идентификаторы должны быть уникальными.document.querySelectorAll()
выделяет все элементы с указанным селектором и возвращает их в массив. Похожий наdocument.getElementsByClassName()
для занятий иdocument.getElementsByTagName()
только теги.
Зачем использовать querySelector?
Он используется исключительно с целью простоты и краткости.
Зачем использовать getElement/sBy?*
Быстрее производительность.
Почему эта разница в производительности?
Оба способа выбора имеют целью создание NodeList для дальнейшего использования. querySelectors генерирует статический NodeList с селекторами, поэтому он должен быть сначала создан с нуля.
getElement / sBy * немедленно адаптирует существующий действующий NodeList текущего DOM.
Итак, когда использовать какой метод зависит от вас / вашего проекта / вашего устройства.
Информация
Демо всех методов
Документация по NodeList
Тест производительности
Вы можете получить один элемент, запустив
document.querySelector('.myElement').style.size = '100px';
но он будет работать для первого элемента с классом.myElement.
Если вы хотите применить это для всех элементов класса, я предлагаю вам использовать
document.querySelectorAll('.myElement').forEach(function(element) {
element.style.size = '100px';
});
Возвращает список, похожий на массив.
Вы делаете этот массив в качестве примера
var el = getElementsByClassName("elem");
el = Array.prototype.slice.call(el); //this line
el[0].appendChild(otherElem);
/*
* To hide all elements with the same class,
* use looping to reach each element with that class.
* In this case, looping is done recursively
*/
const hideAll = (className, i=0) => {
if(!document.getElementsByClassName(className)[i]){ //exits the loop when element of that id does not exist
return;
}
document.getElementsByClassName(className)[i].style.visibility = 'hidden'; //hide element
return hideAll(className, i+1) //loop for the next element
}
hideAll('appBanner') //the function call requires the class name
С ES5+ (любой просмотр в настоящее время - 2017) вы должны быть в состоянии сделать
[].forEach.call(document.getElementsByClassName('answer'), function(el) {
el.style.color= 'red';
});
Супер старое школьное решение:
[].forEach.call(document.getElementsByClassName('myClass'), function (el) {
el.style.size = '100px';
});
Поэтому мне сказали, что это дубликат моего вопроса, и я должен удалить свой, что я и сделаю, чтобы сохранить форум в чистоте и сохранить право задавать вопросы.
Поскольку я думаю, что мой и этот вопрос действительно разные, я укажу ответ на свой, поэтому я дополню знания на этой странице, и информация не будет потеряна.
Вопрос
У меня есть код во фрагменте, который имеет
document.getElementsByClassName("close")[0]
, что делает?Я никогда не видел, чтобы квадратные скобки использовались в
getElementsByClassName
с какой целью он используется?Кроме того, как я могу преобразовать его в jQuery?
Отвечать
Код во фрагменте имеет
[0]
на самом деле он используется как массив, и поскольку он равен 0, он относится к первому использованию назначенного класса.То же самое выше.
Я действительно не мог этого сделать, и никто не ответил на это. В той части кода, которая относится к
event. target
я не могу использовать$("#myModal")
вместоdocument.getElementById("myModal")
, я думаю, они должны быть эквивалентны, но в этом случае замена стандартной jQuery-формы не даст нужного эффекта.
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
Обновить
Кажется, я не могу удалить свой вопрос, и люди им недовольны, я действительно не знаю, что мне делать.
Ответ на конкретный случай Дрензи...
Вы можете создать функцию, которая будет работать для любого изword
элементы и передайте номер того, который вы хотите преобразовать, например:
// Binds `wordButtons` to an (array-like) HTMLCollection of buttons
const wordButtons = document.getElementsByClassName("word");
// Applies the `slantWord` function to the first word button
slantWord(1);
// Defines the `slantWord` function
function slantWord(wordNumber) {
const index = wordNumber - 1; // Collection index is zero-based
wordButtons[index].style.transform = "rotate(7deg)"; // Transforms the specified button
}
<div class="wordGameContainer">
<button class="word word1">WORD 1</button>
<button class="word word2">WORD 2</button>
<button class="word word3">WORD 3</button>
<button class="word word4">WORD 4</button>
</div>
<div>
<button onclick="moveWord()" class="playButton">PLAY</button>
</div>
Это также сработает:
for (let el of document.getElementsByClassName('myElement')) {
el.style.color = 'red';
}
Обязательно заверните все вышесказанное в
window.onload
функция для безопасности, если некоторые элементы появляются после завершения загрузки окна:
window.onload = function() {
for (let el of document.getElementsByClassName('myElement')) {
el.style.color = 'red';
}
}
Скрыть элемент только по имени класса.
document.getElementsByClassName(targetElement)[0].style.display = 'нет';