今日所犯,今日所记。
使用React的useRef绑定DOM节点的时候,发现不能使用getElementById方法,却能使用querySelector方法。
const divRef = React.useRef<HTMLDivElement>()
return (
<div ref={divRef}>
<div id='copyer'>获取id的节点</div>
</div>
)
divRef.current.getElementById('copyer') // 错误:is not a function
divRef.current.querySelector('#copyer') // 正确
说实话,刚开始很迷惑的。但是查清楚原因之后,也就只能怪自己的基础不是很好;
现在的关注点大部分都在react,vue等框架上,基础的知识却往往忽略了。
MDN
对getElementById的解释:
Document
的方法 getElementById()
返回一个匹配特定id的元素。由于元素的 id 在大部分情况下要求是独一无二的,这个方法自然而然地成为了一个高效查找特定元素的方法。
返回值:是一个Element对象。
注意:getElementById()
只有在作为 document
的方法时才能起作用,而在 DOM 中的其他元素下无法生效。
而querySelector
可以应用在其他的节点上。
这也就解释上面所犯的错误。既然都已经聊到这里了,那就看看异步之处吧!
相同点它们是都是获取DOM节点,还是说说不同之处吧。
1、标准不同
querySelector系列属于 W3C 中的Selectors API(JS)规范。 getElementsBy系列则属于 W3C 的DOM 规范。
2、浏览器兼容不同
getElementsBy系列基本所有浏览器都支持。
querySelector系列低版本的浏览器会有问题(IE7都不支持)。
3、接受参数不同
虽然接受的参数都是字符串,但是思维的方式不同。
getElementsBy系列接收的参数为 classname,tagName,name等。
querySelector系列接收的参数为 css选择器
4、性能上有差异
在查找相同节点时,getElementById系列高于querySelector系列。
<body>
<div class="box">
<div class="copyer"></div>
<div class="copyer"></div>
<div class="copyer"></div>
<div class="copyer"></div>
</div>
<script>
for (var i = 0; i < 10000; i++) {
document.querySelectorAll(".copyer");
}
console.timeEnd('querySelectorAll');
//querySelectorAll: 6.867919921875 ms
for (var i = 0; i < 10000; i++) {
document.getElementsByClassName("copyer");
}
console.timeEnd('getElementsByClassName');
//getElementsByClassName: 3.570068359375 ms
</script>
</body>
5、获取的数据状态不一样
getElementById系列获取的集合是动态的;
querySelector系列获取的集合是静态的;
<body>
<div class="box">
<div class="copyer"></div>
<div class="copyer"></div>
<div class="copyer"></div>
<div class="copyer"></div>
</div>
<script>
const x = document.querySelectorAll(".copyer");
const y = document.getElementsByClassName("copyer");
// 动态添加一个节点
const div = document.createElement("div");
div.className = "copyer";
document.getElementsByClassName('box')[0].appendChild(div);
// 分别打印获取节点集合的长度
console.log(x.length); // 4
console.log(y.length); // 5
</script>
</body>
返回值类型总结
getElementById系列:
getElementById() // 根据id查找 返回值:Element对象
getElementsByClassName() // 根据类名查找 返回值:HTMLCollection(集合)
getElementsByName() // 根据name查找 返回值:NodeList (数组)
getElementsByTagName() // 根据标签name查找 返回值:HTMLCollection(集合)
querySelector系列:
querySelector() // 查找第一个元素 返回值:ELement对象
querySelectorAll() // 查找所有元素 返回值:NodeList (数组)