解析JavaScript中 querySelector 与 getElementById 方法的区别

 更新时间:2021年10月28日 12:00  点击:2334 作者:明天也要努力

1. 概述

在看代码的时候发现基本上都是用 querySelector() 和 querySelectorAll() 来获取元素,疑惑为什么不用 getElementById()。
可能因为自己没用过那两个,所以并不清楚原因所在。

1.1 querySelector() 和 querySelectorAll() 的用法

querySelector() 方法

定义:   querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素;
注意:   querySelector() 方法仅返回匹配指定选择器的第一个元素。如果你需要返回所有的元素,请用 querySelectorAll() 方法替代;
语法:   document.querySelector(CSS selectors);
参数值: String  必须。指定一个或多个匹配元素的 CSS 选择器。使用它们的 id, 类, 类型, 属性, 属性值等来选取元素。
        对于多个选择器,使用逗号隔开,返回一个匹配的元素。
返回值:  匹配指定 CSS 选择器的第一个元素。 如果没有找到,返回 null。如果指定了非法选择器则 抛出 SYNTAX_ERR 异常。

querySelectorAll() 方法

定义:   querySelectorAll() 方法返回文档中匹配指定 CSS 选择器的所有元素,返回 NodeList 对象;
         NodeList 对象表示节点的集合。可以通过索引访问,索引值从 0 开始;
提示:    可使用 NodeList 对象的 length 属性来获取匹配选择器的元素属性,然后遍历所有元素,从而获取想要的信息;
语法:   elementList = document.querySelectorAll(selectors);
      elementList 是一个静态的 NodeList 类型的对象;
         selectors 是一个由逗号连接的包含一个或多个 CSS 选择器的字符串;
参数值:  String  必须。指定一个或多个匹配 CSS 选择器的元素。可以通过 id, class, 类型, 属性, 属性值等作为选择器来获取元素。
   多个选择器使用逗号(,)分隔。
返回值:   一个 NodeList 对象,表示文档中匹配指定 CSS 选择器的所有元素。
   NodeList 是一个静态的 NodeList 类型的对象。如果指定的选择器不合法,则抛出一个 SYNTAX_ERR 异常。

1.2 getElement(s)Byxxxx 的用法

getElementById() 方法

定义:  getElementById() 方法可返回对拥有指定 ID 的第一个对象的引用。
  如果没有指定 ID 的元素返回 null;
  如果存在多个指定 ID 的元素则返回第一个;
  如果需要查找到那些没有 ID 的元素,你可以考虑通过CSS选择器使用 querySelector();
语法: document.getElementById(elementID);
参数值: String 必须。元素ID属性值。
返回值:  元素对象 指定ID的元素

getElementsByTagName() 方法

定义:   getElementsByTagName() 方法可返回带有指定标签名的对象的集合;
提示:   参数值 "*" 返回文档的所有元素;
语法: document.getElementsByTagName(tagname)
参数: String 必须  要获取元素的标签名;
返回值: NodeList 对象 指定标签名的元素集合

getElementsByClassName() 方法

定义: getElementsByClassName() 方法返回文档中所有指定类名的元素集合,作为 NodeList 对象。
  NodeList 对象代表一个有顺序的节点列表。NodeList 对象 可通过节点列表中的节点索引号来访问表中的节点(索引号由0开始)。
提示:  可使用 NodeList 对象的 length 属性来确定指定类名的元素个数,并循环各个元素来获取需要的那个元素。
语法:  document.getElementsByClassName(classname)
参数:  String 必须 需要获取的元素类名。  多个类名使用空格分隔,如 "test demo";
返回值: NodeList 对象,表示指定类名的元素集合。元素在集合中的顺序以其在代码中的出现次序排序。

2. 区别

2.1 getElement(s)Byxxxx 获取的是动态集合,querySelector 获取的是静态集合

动态就是选出的元素会随文档改变,静态的不会 取出来之后就和文档的改变无关了。

示例1:

<body>
  <ul id="box">
    <li class="a">测试1</li>
    <li class="a">测试2</li>
    <li class="a">测试3</li>
  </ul>
</body>

<script type="text/javascript">
  //获取到ul,为了之后动态的添加li
  var ul = document.getElementById('box');
  //获取到现有ul里面的li
  var list = ul.getElementsByTagName('li');
  for(var i =0; i < list.length; i++){
    ul.appendChild(document.createElement('li')); //动态追加li
  }
</script>

上述代码会陷入死循环,i < list.length 这个循环条件。
因为在第一次获取到里面的 3 个 li 后,每当往 ul 里添加了新元素后,list便会更新其值,重新获取ul里的所有li。
也就是 getElement(s)Byxxxx 获取的是动态集合,它总会随着 dom 结构的变化而变化。
也就是每一次调用 list 都会重新对文档进行查询,导致无限循环的问题。

示例1 修改:

将 for 循环条件修改为 i < 4,结果 在 ul 里新添加了4个元素,所有现在插入的 li 标签数量是7。

<body>
  <ul id="box">
    <li class="a">测试1</li>
    <li class="a">测试2</li>
    <li class="a">测试3</li>
  </ul>
</body>

<script type="text/javascript">
  var ul = document.getElementById('box');

  var list = ul.getElementsByTagName('li');
  for(var i = 0; i < 4; i++){
    ul.appendChild(document.createElement('li'));
  }
  console.log('list.length:',list.length);
</script>

在这里插入图片描述

示例2:

下述代码静态集合体现在 .querySelectorAll(‘li') 获取到 ul 里所有 li 后,不管后续再动态添加了多少 li,都是不会对其参数影响。

<body>
  <ul id="box">
    <li class="a">测试1</li>
    <li class="a">测试2</li>
    <li class="a">测试3</li>
  </ul>
</body>

<script type="text/javascript">
  var ul = document.querySelector('ul');

  var list = ul.querySelectorAll('li');
  for(var i = 0; i < list.length; i++){
    ul.appendChild(document.createElement('li'));
  }
  console.log('list.length:',list.length); //输出的结果仍然是 3,不是此时 li 的数量 6
</script>

在这里插入图片描述

为什么要这样设计呢?
在 W3C 规范中对 querySelectorAll 方法有明确规定:

The NodeList object returned by the querySelectorAll() method must be static ([DOM], section 8).

我们再看看在 Chrome 上面是个什么样的情况:

document.querySelectorAll('a').toString();    // return "[object NodeList]"
document.getElementsByTagName('a').toString();    // return "[object HTMLCollection]"

HTMLCollection 在 W3C 的定义如下:

An HTMLCollection is a list of nodes. An individual node may be accessed by either ordinal index or the node's name or id attributes.Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.

实际上,HTMLCollection 和 NodeList 十分相似,都是一个动态的元素集合,每次访问都需要重新对文档进行查询。
区别:HTMLCollection 属于 Document Object Model HTML 规范,而 NodeList 属于 Document Object Model Core 规范。
这样说有点难理解,看看下面的例子会比较好理解:

var ul = document.getElementsByTagName('ul')[0],
    lis1 = ul.childNodes,
    lis2 = ul.children;
console.log(lis1.toString(), lis1.length);    // "[object NodeList]" 11
console.log(lis2.toString(), lis2.length);    // "[object HTMLCollection]" 4

NodeList 对象会包含文档中的所有节点,如 Element、Text 和 Comment 等;
HTMLCollection 对象只会包含文档中的 Element 节点;
另外,HTMLCollection 对象比 NodeList 对象 多提供了一个 namedItem 方法;
因此在浏览器中,querySelectorAll 的返回值是一个静态的 NodeList 对象,而 getElementsBy 系列的返回值实际上是一个 HTMLCollection 对象 。

2.2 接收的参数不同

querySelectorAll 方法接收的参数是一个 CSS 选择符;
getElementsBy 系列接收的参数只能是单一的 className、tagName 和 name;

var c1 = document.querySelectorAll('.b1 .c');
var c2 = document.getElementsByClassName('c');
var c3 = document.getElementsByClassName('b2')[0].getElementsByClassName('c');

注意:querySelectorAll 所接收的参数是必须严格符合 CSS 选择符规范的
下面这种写法,将会抛出异常(CSS 选择器中的元素名,类和 ID 均不能以数字为开头)。

try {
  var e1 = document.getElementsByClassName('1a2b3c');
  var e2 = document.querySelectorAll('.1a2b3c');
} catch (e) {
  console.error(e.message);
}
console.log(e1 && e1[0].className);
console.log(e2 && e2[0].className);

2.3 浏览器兼容不同

querySelectorAll 已被 IE 8+、FF 3.5+、Safari 3.1+、Chrome 和 Opera 10+ 支持 ;
getElementsBy 系列,以最迟添加规范中的 getElementsByClassName 为例,IE 9+、FF 3 +、Safari 3.1+、Chrome 和 Opera 9+ 都已经支持;

2.4 querySelector 属于 W3C 中的 Selectors API 规范 ,而 getElementsBy 系列属于 W3C 的 DOM 规范

参考文章 (侵删)

到此这篇关于JavaScript中 querySelector 与 getElementById 方法的区别的文章就介绍到这了,更多相关js中 querySelector 与 getElementById 方法内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

原文出处:https://blog.csdn.net/ZYS10000/article/details/120929920

[!--infotagslink--]

相关文章

  • JavaScript判断浏览器及其版本信息

    本篇文章主要分享了通过window.navigator来判断浏览器及其版本信息的实例代码。具有一定的参考价值,下面跟着小编一起来看下吧...2017-01-23
  • js实现浏览器打印功能的示例代码

    这篇文章主要介绍了js如何实现浏览器打印功能,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-15
  • Nest.js参数校验和自定义返回数据格式详解

    这篇文章主要给大家介绍了关于Nest.js参数校验和自定义返回数据格式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-28
  • 利用JS实现点击按钮后图片自动切换的简单方法

    下面小编就为大家带来一篇利用JS实现点击按钮后图片自动切换的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-25
  • 详解前端安全之JavaScript防http劫持与XSS

    作为前端,一直以来都知道HTTP劫持与XSS跨站脚本、CSRF跨站请求伪造。防御这些劫持最好的方法是从后端入手,前端能做的太少。而且由于源码的暴露,攻击者很容易绕过防御手段。但这不代表我们去了解这块的相关知识是没意义的,本文的许多方法,用在其他方面也是大有作用。...2021-05-24
  • js实现调用网络摄像头及常见错误处理

    这篇文章主要介绍了js实现调用网络摄像头及常见错误处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-07
  • JS实现随机生成验证码

    这篇文章主要为大家详细介绍了JS实现随机生成验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-06
  • js组件SlotMachine实现图片切换效果制作抽奖系统

    这篇文章主要介绍了js组件SlotMachine实现图片切换效果制作抽奖系统的相关资料,需要的朋友可以参考下...2016-04-19
  • vue.js 表格分页ajax 异步加载数据

    Vue.js通过简洁的API提供高效的数据绑定和灵活的组件系统.这篇文章主要介绍了vue.js 表格分页ajax 异步加载数据的相关资料,需要的朋友可以参考下...2016-10-20
  • 基于JavaScript实现文字超出部分隐藏

    这篇文章主要介绍了基于JavaScript实现文字超出部分隐藏 的相关资料,需要的朋友可以参考下...2016-03-01
  • js实现列表按字母排序

    这篇文章主要为大家详细介绍了js实现列表按字母排序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-11
  • js实现上传图片及时预览

    这篇文章主要为大家详细介绍了js实现上传图片及时预览的相关资料,具有一定的参考价值,感兴趣的朋友可以参考一下...2016-05-09
  • JS实现响应鼠标点击动画渐变弹出层效果代码

    这篇文章主要介绍了JS实现响应鼠标点击动画渐变弹出层效果代码,具有非常自然流畅的动画过度效果,涉及JavaScript针对鼠标事件的响应及页面元素样式的动态操作相关技巧,需要的朋友可以参考下...2016-03-28
  • NodeJS实现阿里大鱼短信通知发送

    本文给大家介绍的是nodejs实现使用阿里大鱼短信API发送消息的方法和代码,有需要的小伙伴可以参考下。...2016-01-20
  • 浅析AngularJS Filter用法

    系统的学习了一下angularjs,发现angularjs的有些思想根php的模块smarty很像,例如数据绑定,filter。如果对smarty比较熟悉的话,学习angularjs会比较容易一点,这篇文章给大家介绍angularjs filter用法详解,感兴趣的朋友一起学习吧...2015-12-29
  • node.JS md5加密中文与php结果不一致怎么办

    这次文章要给大家介绍的是node.JS md5加密中文与php结果不一致怎么办,不知道具体解决办法的下面跟小编一起来看看。 因项目需要,需要Node.js与PHP做接口调用,发现nod...2017-07-06
  • js+css实现回到顶部按钮(back to top)

    这篇文章主要为大家详细介绍了js+css实现回到顶部按钮back to top回到顶部按钮,感兴趣的小伙伴们可以参考一下...2016-03-03
  • 基于JavaScript实现表单密码的隐藏和显示出来

    为了网站的安全性,很多朋友都把密码设的比较复杂,但是如何密码不能明显示,不知道输的是对是错,为了安全起见可以把密码显示的,那么基于js代码如何实现的呢?下面通过本文给大家介绍JavaScript实现表单密码的隐藏和显示,需要的朋友参考下...2016-03-03
  • 一个关于JS正则匹配的踩坑记录

    这篇文章主要给大家介绍了一个关于JS正则匹配的踩坑记录,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-13
  • Vue.js中轻松解决v-for执行出错的三个方案

    v-for标签可以用来遍历数组,将数组的每一个值绑定到相应的视图元素中去,下面这篇文章主要给大家介绍了关于在Vue.js中轻松解决v-for执行出错的三个方案,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。...2017-06-15