在日常开发中,使用JavaScript获取元素的时候,最常用的方法就是document.getElementById(getXXXByXX)方法。但是最近发现有很多地方使用的是querySelector方法而不是使用前面的方法。去官方文档查看是这么说的:

文档对象模型Document引用的querySelector()方法返回文档中与指定选择器或选择器组匹配的第一个 html元素Element。 如果找不到匹配项,则返回null


这句话看意思和getElementById(getXXXByXX)函数是一样的。其实大部分的时候这两种方法是可以互换的,这里介绍一下两者的不同之处。

其实这两种方法的区别就是获取动态集合静态集合的关系。

  • getElementById()(getXXXByXX)获取动态集合:通过函数获取元素之后,元素之后的改变还是会动态添加到已经获取的这个元素中。换句话说,通过这个方法获取到元素存储到变量的时候,以后每一次在Javascript函数中使用这个变量的时候都会再去访问一下这个变量对应的html元素。
  • querySelector()获取静态集合:通过函数获取元素之后,元素之后的改变并不会影响之前获取后存储到的变量。也就是获取到元素之后就和html中的这个元素没有关系了。

通过一个例子就比较好理解了:

<!DOCTYPE html>
<html>
<head>
<title>querySelector()和getElementById()的区别</title>
</head>
<body>
<ul id="testUl">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script type="text/javascript">
var testUl = document.getElementsByTagName('ul')[0];
var liList = testUl.getElementsByTagName('li');
for (var i = 0; i < liList.length; i++) {
console.log(liList.length);
/** 向ul中追加li标签 */
testUl.appendChild(document.createElement('li'));
}
</script>
</body>
</html>

这段代码初始的意思是想要向ul中添加目前已经有的等量的li标签子元素。但通过getElementsByTagName实现这个问题的时候会出现下面的结果:

使用这个方法实现的时候,程序会形成一个死循环。原因是在for循环中每次执行完毕后会判断 i 和 liList.length 的关系,之前说到,每一次使用 liList 这个变量的时候会再去访问一下对应的html元素,但通过for循环中的语句,每次执行一遍后liList会增加一个元素,这就导致liList.length一直增加,从而不会到达循环的结束条件,形成死循环。

同样的代码将JavaScript中的处理语句替换成下面的语句:

<script type="text/javascript">
var testUl = document.querySelector('ul');
var liList = testUl.querySelectorAll('li');
for (var i = 0; i < liList.length; i++) {
console.log(liList.length);
/** 向ul中追加li标签 */
testUl.appendChild(document.createElement('li'));
}
</script>
  • querySelectorAll表示获取到所有满足条件的元素,返回的是一个列表。

执行结果如下:

可以看到,在第16行也就是for循环中输出了三次3,也就是一开始 li 标签的个数。for循环执行完毕后我在第20行加了console.log(liList.length)语句,输出的还是3,而重新获取一下后再输出一下长度就已经变成了6。这就说明了一个问题:获取到元素之后,只要我不重新使用语句再次获取这个元素,之前的变量就一直不会改变,也就是说,通过querySelector(querySelectorAll)获取到元素之后,不论html元素再怎么改变,这个变量并不会随之发生改变,这个变量已经和html元素没有任何关系了。

这就是JavaScript中querySelector()和getElementById()(getXXXByXX)的区别,虽然大部分时间两者可以互换,但是最好在使用的过程中先斟酌一下是否可以使用其中的某一个,避免出现死循环导致程序都关不了。

JavaScript中querySelector()和getElementById()(getXXXByXX)的区别的更多相关文章

  1. JavaScript中const、var和let区别浅析

    在JavaScript中有三种声明变量的方式:var.let.const.下文给大家介绍js中三种定义变量的方式const, var, let的区别. 1.const定义的变量不可以修改,而且必须初始 ...

  2. JavaScript中值类型和引用类型的区别

    JavaScript的数据类型分为两类:原始类型和对象类型.其中,原始类型包括:数字.字符串和布尔值.此外,JavaScript中还有两个特殊的原始值:null和undefined,它们既不是数字也不 ...

  3. JavaScript中=、==、===以及!=、!==的区别与联系

    JavaScript中=.==.===以及!=.!==的区别与联系   在JavaScript中,“=”代表赋值操作:“==”先转换类型再比较,“===”先判断类型,如果不是同一类型直接为false. ...

  4. JavaScript中object和Object有什么区别

    JavaScript中object和Object有什么区别,为什么用typeof检测对象,返回object,而用instanceof 必须要接Object呢 ————————————————————— ...

  5. 深入理解Javascript中构造函数和原型对象的区别

    在 Javascript中prototype属性的详解 这篇文章中,详细介绍了构造函数的缺点以及原型(prototype),原型链(prototype chain),构造函数(constructor) ...

  6. 关于javascript中apply()和call()方法的区别

    如果没接触过动态语言,以编译型语言的思维方式去理解javaScript将会有种神奇而怪异的感觉,因为意识上往往不可能的事偏偏就发生了,甚至觉得不可理喻.如果在学JavaScript这自由而变幻无穷的语 ...

  7. javascript 中 offsetWidth,clientWidth;offsetHeight,clientHeight的区别

    javascript 中 offsetWidth 是对象的可见宽度,包滚动条等边线,会随窗口的显示大小改变 clientWidth.offsetWidth.clientHeight区别IE6.0.FF ...

  8. 在 JavaScript 中 prototype 和 __proto__ 有什么区别

    本文主要讲三个 问题 prototype 和 proto function 和 object new 到底发生了什么 prototype 和 proto 首先我们说下在 JS 中,常常让我们感到困惑的 ...

  9. javascript中的undefined与null的区别

    一.相似性 在JavaScript中,将一个变量赋值为undefined或null,老实说,几乎没区别. var a = undefined; var a = null; 上面代码中,a变量分别被赋值 ...

随机推荐

  1. 时间戳转分秒 | 字符串的padStart()和padEnd()

    function _pad(num, n = 2) { let len = num.toString().length while (len < n) { num = '0' + num len ...

  2. Tomcat 8 Invalid character found in the request target. The valid characters are defined in RFC 3986

    终极解决方案: Invalid character found in the request target. The valid characters are defined in RFC 3986 ...

  3. SpringBoot 集成FreeMarker

    SpringBoot官方不推荐使用jsp,因为jsp不好发挥SpringBoot的特性.官方推荐使用模板引擎代替jsp,现在很多公司都使用FreeMarker来作为SpringBoot的视图. Spr ...

  4. SQL注入之SQLmap

    注意:sqlmap只是用来检测和利用sql注入点的,并不能扫描出网站有哪些漏洞,使用前请先使用扫描工具扫出sql注入点. 1.

  5. 洛谷 P5242 [USACO19FEB]Cow Dating P

    这道题很有意思. 不难发现,对于一个区间 \([l, r]\),恰好只有一个奶牛接受邀请的概率为 \[\prod_{i=l}^r(1-p_i) \cdot \sum_{i=l}^r \frac {p_ ...

  6. PLSQL设置显示的字符集及设置

    一.关于PLSQL无法正确显示中文 刚才下载安装了PLSQL Developer 9.0.0.1601 汉化绿色版,执行SQL查询语句,发现显示的数据中只要有中文都会以?表示.经过网上查询得知这是客户 ...

  7. 如何关闭 Mac OS X EI Capitan 系统文件保护

    在修改 Mac OS X EI Capitan 系统的某些系统文件的过程中,你可能会遇到即使你加了 sudo 以管理员身份去操作页会被拒绝, 这是一个名为 SIP(System Integrity P ...

  8. 8张图片掌握JS原型链

  9. Mysql8.0免安装包配置方法

    1. 官网下载mysql_8.0.12免安装包,解压到你存放的地方: https://www.jb51.net/softs/609101.html 2. 配置环境变量(把bin的文件夹弄进系统path ...

  10. 对S7通信的连接的理解以及对比CAN通信协议来理解PLC通讯

    对S7通信的连接的理解以及对比CAN通信协议来理解PLC通讯. 对功能块 SFB12 和 SFB13 的R_ID参数的理解 ? 对于同一个数据包.发送方与接收方的R_ID应该相同. 用下图解释 双向连 ...