Перебрать ВСЕ элементы DOM не работают
В "демонстрационном" div я хочу показать идентификатор getAttribute и стиль всех элементов (в данном случае два элемента - demone и demotwo). Если я удалю цикл, отображаются только идентификатор и стиль первого элемента, и все работает нормально. Как только добавляю, цикл перестает работать, в чем я ошибаюсь.
function myFunction() {
var divs = document.querySelectorAll('*'),
i;
for (i = 0; i < divs.length; ++i) {
var div = divs[i];
var id = document.getElementById(div).getAttribute("id");
var sty = document.getElementById(div).getAttribute("style");
document.getElementById("demo").innerHTML = "Id element: " + id + " Style element: " + sty + "";
}
}
<div id="demoone" style="width:50px;height:60px;">One</div>
<div id="demotwo" style="width:30px;height:40px;">Two</div>
<button onclick="myFunction()">Try it</button>
<div id="demo"></div>
2 ответа
Основная проблема заключается в том, что вы используете индекс цикла для изоляции div
элемент, а затем используя фактический div
элемент в качестве аргумента, который вы передаете getElementById()
. Чтобы получить элемент по егоid
вы должны передать строку, которая соответствует фактическому id
атрибут, используемый в HTML.
Но есть более простой способ, который не требует знания id
любого элемента. Вместо цикла подсчета, переберите массив элементов, которые вы найдете с помощью Array.forEach()
метод. Это позволяет избежать использования счетчика. Кроме того, если вы собираетесь смотреть только наdiv
элементы, измените свой селектор с *
к div
.
Кроме того, в конце, когда вы записываете свои результаты в свой demo
элемент, вы устанавливаете .innerHTML
с =
. Это приведет к тому, что любое предыдущее значение будет выброшено, поэтому вы не получите отчет обо всех элементах, вы просто увидите информацию из последнего элемента, который прошел цикл. Вместо этого используйте+=
, который объединяет новое значение с последним значением. Кроме того, никогда не обновляйте.innerHTML
в цикле, так как это приведет к многократному обновлению DOM, что приведет к множеству перерисовок и перекомпоновок, что может быть дорогостоящим. Вместо этого создавайте строку по мере продвижения по циклу, а когда цикл будет завершен, обновите свой элемент только один раз с этой строкой.
Наконец, не рекомендуется настраивать события через атрибуты HTML (onclick
). Вместо этого отделите свой JavaScript от своего HTML и выполните обработку событий с помощью.addEventListener()
.
<div id="demoone" style="width:50px;height:60px;">One</div>
<div id="demotwo" style="width:30px;height:40px;">Two</div>
<button>Try it</button>
<div id="demo"></div>
<script>
// Do event handling the modern way, not with inline HTML:
document.querySelector("button").addEventListener("click", myFunction);
function myFunction() {
// Get reference to the output element
let output = document.getElementById("demo");
// Get all the elements and convert the collection into an Array
var divs = Array.prototype.slice.call(document.querySelectorAll('div'));
// Loop over the array
let results = "";
divs.forEach(function(div){
results += "<br>Id element: " + div.id + " Style element: " + div.getAttribute("style") + "";
});
output.innerHTML = results; // Inject string into the element
}
</script>
querySelectorAll()
не возвращает идентификаторы, а возвращает сами элементы. Так что тебе не нужно звонитьgetElementById()
до получения атрибута.
Если вы хотите увидеть информацию обо всех элементах, вам нужно добавить сообщение в HTML-код DIV, а не перезаписывать его каждый раз в цикле.
function myFunction() {
var divs = document.querySelectorAll('*'),
i;
document.getElementById("demo").innerHTML = ''; // start with empty DIV
for (i = 0; i < divs.length; ++i) {
var div = divs[i];
var id = div.getAttribute("id");
var sty = div.getAttribute("style");
document.getElementById("demo").innerHTML += "Id element: " + id + " Style element: " + sty + "<br>";
}
}
<div id="demoone" style="width:50px;height:60px;">One</div>
<div id="demotwo" style="width:30px;height:40px;">Two</div>
<button onclick="myFunction()">Try it</button>
<div id="demo"></div>