JavaScript系列:getElementById与querySelector的区别

478 阅读2分钟

今日所犯,今日所记。

使用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 (数组)