querySelectorAll 和 getElementsBy* 方法返回什么
What do querySelectorAll and getElementsBy* methods return?
getElementsByClassName
(以及类似的函数,如getElementsByTagName
和querySelectorAll
)的工作方式与getElementById
相同,还是返回元素数组?
我问的原因是因为我正在尝试使用 getElementsByClassName
更改所有元素的样式。见下文。
//doesn't work
document.getElementsByClassName('myElement').style.size = '100px';
//works
document.getElementById('myIdElement').style.size = '100px';
您的getElementById
代码有效,因为 ID 必须是唯一的,因此该函数始终只返回一个元素(如果未找到元素,则返回null
元素)。
但是,方法 getElementsByClassName
, getElementsByName
, getElementsByTagName
和 getElementsByTagNameNS
返回元素的可迭代集合。
方法名称提供了提示:getElement
表示单数,而getElements
表示复数。
该方法还返回单个元素querySelector
,querySelectorAll
返回可迭代集合。
可迭代集合可以是NodeList
,也可以是HTMLCollection
。
getElementsByName
和querySelectorAll
都被指定为返回NodeList
;其他getElementsBy*
方法被指定为返回HTMLCollection
,但请注意,某些浏览器版本实现这一点的方式不同。
这两种集合类型都不提供与元素、节点或类似类型相同的属性;这就是为什么从document.getElements
中读取style
的原因......(
......)
失败。换句话说:NodeList
或HTMLCollection
没有style
;只有Element
才有style
.
"类似数组"的集合是包含零个或多个元素的列表,您需要迭代这些元素才能访问它们。虽然您可以像数组一样迭代它们,但请注意它们与 Array
s 不同。
在现代浏览器中,你可以用Array.from
将这些迭代对象转换为适当的数组;然后你可以使用forEach
和其他数组方法,例如迭代方法:
Array.from(document.getElementsByClassName("myElement"))
.forEach((element) => element.style.size = "100px");
在不支持Array.from
或迭代方法的旧浏览器中,您仍然可以使用 Array.prototype.slice.call
。然后你可以像使用真实数组一样迭代它:
var elements = Array.prototype.slice
.call(document.getElementsByClassName("myElement"));
for(var i = 0; i < elements.length; ++i){
elements[i].style.size = "100px";
}
你也可以迭代NodeList
或HTMLCollection
本身,但要注意,在大多数情况下,这些集合是实时的(MDN 文档、DOM 规范),即它们随着 DOM 的变化而更新。因此,如果在循环时插入或删除元素,请确保不要意外跳过某些元素或创建无限循环。MDN 文档应始终注意方法返回的是实时集合还是静态集合。
例如,NodeList
提供了一些迭代方法,例如现代浏览器中的forEach
:
document.querySelectorAll(".myElement")
.forEach((element) => element.style.size = "100px");
也可以使用简单的for
循环:
var elements = document.getElementsByClassName("myElement");
for(var i = 0; i < elements.length; ++i){
elements[i].style.size = "100px";
}
旁白:.childNodes
产生一个活NodeList
,.children
产生一个活HTMLCollection
,所以这两个获取者也需要小心处理。
有一些像jQuery这样的库,它使DOM查询更短一些,并在"一个元素"和"一个元素集合"上创建了一个抽象层:
$(".myElement").css("size", "100px");
你使用数组作为对象,getElementbyId
和 getElementsByClassName
是:
-
getElementbyId
将返回一个 Element 对象,如果未找到具有 ID 的元素,则返回 null -
getElementsByClassName
将返回一个实时的 HTMLCollection,如果未找到匹配的元素,则长度可能为 0
getElementsByClassName
getElementsByClassName(classNames)
方法采用一个字符串 包含一组无序的唯一空格分隔标记 表示类。调用时,该方法必须返回实时NodeList
对象,包含文档中所有元素 具有该参数中指定的所有类,并获得了 通过在空格上拆分字符串来类。如果没有令牌 在参数中指定,则该方法必须返回空 节点列表。
https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#getelementsbyclassname
getElementById
getElementById() 方法访问具有指定 id 的第一个元素。
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
在您的代码中,这些行:
1- document.getElementsByClassName('myElement').style.size = '100px';
不会按预期工作,因为getElementByClassName
将返回一个数组,并且该数组将没有 style
属性,您可以通过遍历每个element
来访问它们。
这就是为什么该函数getElementById
为您工作的原因,该函数将返回直接对象。因此,您将能够访问style
属性。
ES6 提供了Array.from()
方法,该方法从类似数组或可迭代的对象创建新的 Array 实例。
let boxes = document.getElementsByClassName('box');
setTimeout(() => {
Array.from(boxes).forEach(v => v.style.background = 'green');
console.log(Array.from(boxes));
}, 500);
.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 对象。
对象表示节点的集合。节点可以是通过索引号访问。指数从 0 开始。
提示: 您可以使用 NodeList 对象的 length 属性来确定具有指定类名的元素数,然后您可以遍历所有元素并提取所需的信息。
因此,作为参数,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>
的集合(不是数组),因为它们与给定的类名匹配。
然后,您可以使用以下命令循环访问此节点(在本例中为 <div>
s)集合:
for (var menuItemIndex = 0 ; menuItemIndex < menuItems.length ; menuItemIndex ++) {
var currentMenuItem = menuItems[menuItemIndex];
// do stuff with currentMenuItem as a node.
}
有关元素和节点之间差异的更多信息,请参阅此帖子。
document.querySelector()
仅选择指定选择器的前一个元素。所以它不会吐出一个数组,它是一个单一的值。类似于仅获取 ID 元素的document.getElementById()
,因为 ID 必须是唯一的。document.querySelectorAll()
使用指定的选择器选择所有元素,并在数组中返回它们。类似于仅对类和document.getElementsByTagName()
标签document.getElementsByClassName()
。
为什么使用 querySelector?
它仅用于方便和简洁的唯一目的。
为什么使用 getElement/sBy?*
更快的性能。
为什么会有这种性能差异?
这两种选择方式的目的都是创建一个节点列表以供进一步使用。querySelectors 使用选择器生成一个静态 NodeList,因此必须首先从头开始创建它。
getElement/sBy* 会立即调整当前 DOM 的现有实时 NodeList。
因此,何时使用哪种方法取决于您/您的项目/您的设备。
信息
所有方法
的演示节点列表文档
Performance Test
您可以通过运行来获取单个元素
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+ 的浏览器(任何基本上高于 IE8 的浏览器),您可以使用 Array.prototype.forEach
方法。
Array.prototype.forEach.call(document.getElementsByClassName('answer'), function(el) {
el.style.color= 'red';
});
犬源
所以我被告知这是我的问题的副本,我应该删除我的问题,我会这样做,这样我就可以保持论坛干净并保持提问的权利。
由于我认为我的和这个问题确实不同,因此我将指出我的答案,因此我将完成此页面中的知识,并且信息不会丢失。
问题
-
我在代码片段中有一个
document.getElementsByClassName("close")[0]
的代码,[0]
在做什么? -
我从未见过方括号用于
getElementsByClassName
它的目的是什么? -
另外,如何将其转换为jQuery?
答
- 代码
片段中的代码有一个
[0]
它实际上被用作数组,因为它是 0,它指的是第一次使用指定的类。上面也一样。
我真的做不到,也没有人回答。在引用的代码部分
event. target
我不能使用$("#myModal")
代替document.getElementById("myModal")
,我认为它们应该等效,但在这种情况下,替换标准形式的jQuery形式不会产生预期的效果。
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
var modal = document.getElementById("myModal");
var btn = document.getElementById("myBtn");
var span = document.getElementsByClassName("close")[0];
btn.onclick = function() {
modal.style.display = "block";
}
span.onclick = function() {
modal.style.display = "none";
}
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
body {font-family: Arial, Helvetica, sans-serif;}
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
.close {
color: #aaaaaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
<h2>Modal </h2>
<button id="myBtn">Open Modal</button>
<div id="myModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<p>Some text in the Modal..</p>
</div>
</div>
更新
看来我真的不能删除我的问题,人们对它不满意,我真的不知道我应该怎么做。
超级老派解决方案:
[].forEach.call(document.getElementsByClassName('myClass'), function (el) {
el.style.size = '100px';
});
Drenzii具体情况的答案...
您可以创建一个适用于任何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>
- 它将返回什么新日期(DateObject)
- 如果statusCode不是200,那么从http调用返回什么类型的错误对象
- Dijkstra的算法应该返回什么
- 具有多个返回语句的函数返回什么
- 如果未找到搜索方法,则应返回什么
- 如果字符串不匹配,.split() 返回什么
- querySelectorAll 和 getElementsBy* 方法返回什么
- 获取 0 的文档元素返回什么
- unescape()函数返回什么
- 我的函数应该通过.fail()回调为Ajax请求返回什么
- backbonejs入门-服务器应该返回什么
- 当index=-1时,JS在请求myArray[index]时返回什么
- 如果在已经是最后一个元素上调用jQuery.next方法,那么它会返回什么
- 从父函数返回什么以获取从子函数/嵌套函数返回的值
- getCurrentPosition返回什么
- 以下Javascript语句返回什么以及为什么返回
- String.charAt() 在给定一个无法解析为 int 的字符串的情况下返回什么
- 递归闭包返回什么?
- 对于非异步路径返回什么
- 在等待$onInit回调完成时,我应该为Angular绑定的属性返回什么?