选择器是Css 非常强大的功能,早先一般是通过getElementById 和getElementsByTagName 来获取页面元素,在一些场景下就很不方便。 后来DOM扩展出了Selector API 标准,其中 Selector API Level 1 包含了querySelector 和querySelectorAll 两个方法,可以通过Css选择器匹配页面元素。
一、querySelector查询单个元素querySelector 用于查询页面中第一个符合规则的元素,可以在Document 实例和Element 实例上调用,接收一个选择器字符串参数,如果查找到则返回 HTMLElement 对象,否则返回null 。
语法格式如下: Document实例.querySelector(选择器字符串);Element实例.querySelector(选择器字符串);
1. Document实例调用Document 实例调用是获取整个页面匹配的元素。
简单示例如下: // 获取body元素let body = document.querySelector("body");console.log(body)// 获取id为container的元素,只会获取第一个let container = document.querySelector("#container");console.log(container)// 获取class中包含btn的元素,只会获取第一个let btn = document.querySelector(".btn");console.log(btn);// 获取container直接子类class中包含btn的元素,只会获取第一个let containerBtn = document.querySelector("#container>.btn");console.log(containerBtn);
2. Element实例调用Element 实例调用是获取该元素子树内匹配的元素。
简单示例: // 获取ID为container的元素let container = document.querySelector("#container");// 需要检测元素对象是否存在,存在才有 querySelector 方法if (container) { // 只查找 container 内class包含 btn 的元素。 let containerBtn = container.querySelector(".btn"); console.log(containerBtn);} 理论上来讲,因为Css可以通过选择器获取页面任意的元素,所以Element 实例调用可以直接写成Document 实例的调用方式,只需要修改选择器字符串参数即可。 例如上例就可以直接写成如下方式: let containerBtn = document.querySelector("#container .btn"); 并且因为少了一个if判断,代码就更加简洁。当然在有些业务场景下,ELement 实例是已经确定的了,那么直接用 ELement 实例 调用就更加方便了。
二、querySelectorAll查询所有元素querySelectorAll 方法和querySelector 方法类似,只是它是返回所有匹配的元素,类型是NodeList 。
简单示例: // 假设页面有两个div类名包含 article// 获取所有类包含 article 的元素let articleList = document.querySelectorAll(".article");console.log(articleList);console.log(articleList.length);// 控制台输出:// NodeList(2) [div.article, div.article]// 2 querySelectorAll 方法返回的是所有元素,在实务中经常需要遍历,遍历可以使用常规的for 遍历、for of 遍历和forEach 遍历。
// for of 遍历for (let item of articleList) { console.log(item);}// for 遍历for (let i = 0; i < articleList.length; i++) { console.log(articleList[i]); console.log(articleList.item(i));}// forEach 遍历articleList.forEach((item, index) => { console.log(item, index);});
1、for in遍历的问题如果使用for in 遍历,则会把原型链上的一些方法也遍历出来,如entries ,forEach 等。
2、快照而非实时的问题使用querySelectorAll 方法获取的NodeList 是快照,而非实时的数据。 请看下面这个例子: // 使用 querySelectorAll 获取,articleList 是静态的,非实时的let articleList = document.querySelectorAll(".article");console.log(articleList);console.log(articleList.length); // 2setTimeout(() => { // 增加一个元素 let div = document.createElement("div"); div.className = "article"; document.body.appendChild(div); console.log(articleList); // 依旧为2 console.log(articleList.length);}, 0); 最后设置了一个定时器,往页面塞了一个class 为article 的div 元素,但是 articleList 的长度依旧是2。 如果是用getElementsByClassName 获取,那么 articleList 就是实时的数据。 请看如下例子: // 使用 getElementsByClassName 获取,articleList是实时的let articleList = document.getElementsByClassName("article");console.log(articleList);console.log(articleList.length);setTimeout(() => { // 增加一个元素 let div = document.createElement("div"); div.className = "article"; document.body.appendChild(div); console.log(articleList); // 这里为3 console.log(articleList.length);}, 0); 在控制台查看打印结果: HTMLCollection动态效果: 
使用 getElementsByClassName 获取的对象是 HTMLCollection 类型,会随文档流变化而变化。 下载地址: 关于JavaScript Echart图表在项目中的前后端使用详解 |