在日常开发中,使用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)的区别,虽然大部分时间两者可以互换,但是最好在使用的过程中先斟酌一下是否可以使用其中的某一个,避免出现死循环导致程序都关不了。

最新文章

  1. iOS工作笔记(十五)
  2. 多选列表Select之双击删除与添加Demo
  3. How to create QTP Shared Object Repository
  4. 清风注解-Swift程序设计语言
  5. F数圈圈
  6. 跟我一起读postgresql源码(八)——Executor(查询执行模块之——可优化语句的执行)
  7. 【转载】MySQL事务以及SELECT ... FOR UPDATE的使用
  8. APP测试点注意事项汇总
  9. arch xfce快捷键
  10. 洛谷P1725--琪露诺(单调队列)
  11. CoreJava(一)—— Java迭代语句
  12. PHP原生处理select结果集的函数介绍
  13. php优秀框架codeigniter学习系列——CI_Output类的学习
  14. uva-519-拼图
  15. 小程序获取view元素的高度
  16. 【题解】 bzoj1503: [NOI2004]郁闷的出纳员 (Splay)
  17. Kubernetes学习之路(十二)之Pod控制器--ReplicaSet、Deployment
  18. 7-15 Square Destroyer 破坏正方形 uva1603
  19. 【RF库Collections测试】Dictionaries Should Be Equal
  20. 个人总结-9-session的使用,十天免登陆

热门文章

  1. 设计模式课程 设计模式精讲 19-2 策略模式coding
  2. Python爬虫教程-爬取5K分辨率超清唯美壁纸源码
  3. 「题解」JOIOI 王国
  4. 精易四周年限量纪念U盘(全套)
  5. js 跳转 XSS漏洞 预防
  6. English-Number
  7. java学习-循环结构-递归练习1-汉诺塔问题
  8. php-计算2个时间之差
  9. Python 网络编程之网络协议(未完待续)
  10. IEEE Spectrum 2014年十大编程语言盘点