面试官:querySelectorAll 和 getElementByClassName 的区别是啥

321 阅读2分钟

前言

标题这个问题是去年年底面试阿里大文娱时被问到的一个很小的八股问题,当时还不清楚二者有啥区别,今天才去了解了下~

那场面试后来也是如期入库,其实并没有可惜,面试官就是来 kpi,因为后来翻看牛客,面的内容都是一样的。。。

进入正题,原生 html 去批量拿到 dom 元素,我们可以用这两种方式,但是二者返回的类型却又不同,querySelectorAll 返回的是 NodeList 类型,而 getElementByClassName 返回的是 HTMLCollection 类型,前者是静态的,后者是动态的,下面就来解释下这个静态和动态的概念

NodeList vs HTMLCollection

先看个 demo ,我们写了一个 list,原本就是两个 item,然后分别用 querySelectorAllgetElementByClassName 去展示 item 的个数

1.png

为了动态展示 item 个数,没有框架去帮忙响应式更新 页面 ,原生 html 写法上还是比较繁琐的

我们现在试着去点击按钮新增 item

1.gif

可以发现 querySelectorAll 获取的 item 在最初就是确定好的,是静态的;而 getElementByClassName 获取的 item 是动态实时更新的;

最后

知识点很小,但若你不清楚二者返回结果的区别,当你接手的需求需要你动态拿到 item 长度时,你用了 静态的 NodeList 那就会出问题

比如一个网页,前端从后端拿数据,需要判断当前页面数据是否填充满了,要是 div 数量不够,就继续添加,直到填满页面。要是此时用的 querySelectorAll 那就没法实现这个需求了

包括我们复制 node 节点时,若用一个动态 item 去做终止循环条件,那么页面就会出现死循环

let list = document.getElementsByClassName('list')[0];
let listItems = document.getElementsByClassName('list-item');
let btn = document.getElementsByTagName('button')[0];
btn.onclick = function () {
    for (let i = 0; i < listItems.length; i++) {
        let cloned = listItems[i].cloneNode(true);
        list.appendChild(cloned);
    }
};