深入理解javascript选择器API系列第三篇——h5新增的3种selector方法
前面的话
尽管DOM作为API已经非常完善了,但是为了实现更多的功能,DOM仍然进行了扩展,其中一个重要的扩展就是对选择器API的扩展。人们对jQuery的称赞,很多是由于jQuery方便的元素选择器。除了前面已经介绍过的getElementsByClassName()方法外,DOM拓展了querySelectorAll()、querySelector()和matchesSelector()这3种方法,通过CSS选择符查询DOM文档取得元素的引用的功能变成了原生的API,解析和树查询操作在浏览器内部通过编译后的代码来完成,极大地改善了性能。本文将详细介绍html5新增的3种selector方法
方法
querySelector()
querySelector()方法接收一个CSS选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null。该方法既可用于文档document类型,也可用于元素element类型。关于CSS选择器的详细内容移步至此
[注意]IE7-浏览器不支持
<body style="height: 100%;">
<div class="box" id="box" style="height: 200px;">
<ul class="list" style="height:100px">
<li class="in" style="height: 30px;">1</li>
<li class="in" style="height: 30px;" title="test">2</li>
<li class="in" style="height: 30px;">3</li>
</ul>
</div>
<script>
//因为没有.null类名,所以返回null
var oNull = document.querySelector('.null');
console.log(oNull);//null
//通过<body>标签取得元素
var body = document.querySelector("body");
console.log(body.style.height);//100%
//通过id属性取得元素
var oBox = document.querySelector('#box');
console.log(oBox.style.height);//200px
//通过结合元素的类选择器取得元素
var oList = document.querySelector('ul.list');
console.log(oList.style.height);//100px
//通过类名取得元素
var oIn = document.querySelector('.in');
console.log(oIn.innerHTML);//1
//通过属性选择器取得元素
var oTest = body.querySelector('[title="test"]');
console.log(oTest.innerHTML);//2
</script>
</body>
querySelectorAll()
querySelectorAll()接收一个CSS选择符,返回一个类数组对象NodeList的实例。具体来说,返回的值实际上是带有所有属性和方法的NodeList,而其底层实现则类似于一组元素的快照,而非不断对文档进行搜索的动态查询。这样实现可以避免使用NodeList对象通常会引起的大多数性能问题。只要传给querySelectorAll()方法的CSS选择符有效,该方法都会返回一个NodeList对象,而不管找到多少匹配的元素
没有匹配元素时,返回空的类数组对象,而不是null
[注意]IE7-浏览器不支持
<body style="height: 100%;">
<div class="box" id="box" style="height: 200px;">
<ul class="list" style="height:100px">
<li class="in" style="height: 30px;">1</li>
<li class="in" style="height: 30px;" title="test">2</li>
<li class="in" style="height: 30px;">3</li>
</ul>
</div>
<script>
//返回[]
var oNull = document.querySelectorAll('.null');
console.log(oNull);
//取得body元素
var body = document.querySelectorAll("body")[0];
console.log(body.style.height);//100%
//取得所有class为"in"的元素
var oIn = document.querySelectorAll('.in');
for(var i = 0 ; i < oIn.length; i++){
console.log(oIn[i].innerHTML);//1,2,3
}
//取得title属性为test的元素
var oTest = body.querySelectorAll('[title="test"]');
console.log(oTest);//[li.in]
</script>
</body>
matchesSelector()
matchesSelector()方法接收一个CSS选择符参数,如果调用元素与该选择符相匹配,返回true;否则返回false
[注意]一般地,使用matches()方法来替代matchesSelector()方法
<body id="test">
<script>
//Uncaught TypeError: document.body.matchesSelector is not a function
console.log(document.body.matchesSelector('#test'));
</script>
</body>
由于兼容性问题,现在各个浏览器都只支持加前缀的方法。IE9+浏览器支持msMatchesSelector()方法,firefox支持mozMatchesSelector()方法,safari和chrome支持webkitMatchesSelector()方法。所以兼容写法为:
function matchesSelector(element,selector){
if(element.matchesSelector){
return element.matchesSelector(selector);
}
if(element.msMatchesSelector){
return element.msMatchesSelector(selector);
}
if(element.mozMatchesSelector){
return element.mozMatchesSelector(selector);
}
if(element.webkitMatchesSelector){
return element.webkitMatchesSelector(selector);
}
}
<body id="test">
<script>
console.log(matchesSelector(document.body,'#test'));//true
</script>
</body>
非实时
与getElementById()和getElementsByTagName()方法不同,querySelector()和querySelectorAll()方法得到的类数组对象是非动态实时的
<div id="container">
<div>1</div>
<div>2</div>
</div>
<script>
var container = document.getElementById('container');
var divOne = container.querySelector('div:last-child');
var divAll = container.querySelectorAll('div');
console.log(container.children.length);//2
console.log(divOne.innerHTML);//2
console.log(divAll.length);//2 var newDiv = document.createElement('div');
newDiv.innerHTML = 3;
container.appendChild(newDiv); console.log(container.children.length);//3
//由于querySelector不是实时的,所以其保存的仍然是原来第二个div的值
console.log(divOne.innerHTML);//2
//由于querySelectorAll不是实时的,所以仍然只保存了两个div元素
console.log(divAll.length);//2 console.log(container.querySelector('div:last-child').innerHTML);//3
console.log(container.querySelectorAll('div').length);//3
</script>
缺陷
selector类方法在元素上调用时,指定的选择器仍然在整个文档中进行匹配,然后过滤出结果集,以便它只包含指定元素的后代元素。这看起来是违反常规的,因为它意味着选择器字符串能包含元素的祖先而不仅仅是所匹配的元素
<div id="container">
<div>1</div>
<div>2</div>
</div>
<script>
var container = document.getElementById('container');
console.log(container.querySelectorAll('div div'));//[div div]
</script>
按照正常理解,控制台应该返回空的类数组对象,因为id为container的div元素的子元素中,不存在div元素嵌套的情况
但是,该方法实际返回[div div]。这是因为参数中的选择器包含了元素的祖先
所以,如果出现后代选择器,为了防止该问题,可以在参数中显式地添加当前元素的选择器
<div id="container">
<div>1</div>
<div>2</div>
</div>
<script>
var container = document.getElementById('container');
console.log(container.querySelectorAll('#container div div'));//[]
console.log(container.querySelectorAll('#container div'));//[div div]
console.log(container.querySelectorAll('div'));//[div div]
</script>
最后
虽然存在着非实时和参数缺陷的问题,但是瑕不掩瑜,selector类方法的出现极大地简化了查找元素的繁琐操作。而且,它们支持IE8浏览器
javascript选择器API系列写完了,欢迎交流
深入理解javascript选择器API系列第三篇——h5新增的3种selector方法的更多相关文章
- 深入理解javascript选择器API系列第三篇——HTML5新增的3种selector方法
前面的话 尽管DOM作为API已经非常完善了,但是为了实现更多的功能,DOM仍然进行了扩展,其中一个重要的扩展就是对选择器API的扩展.人们对jQuery的称赞,很多是由于jQuery方便的元素选择器 ...
- 深入理解javascript选择器API系列第一篇——4种元素选择器
× 目录 [1]id属性 [2]标签名 [3]name属性[4]all 前面的话 说到最常见的DOM应用,恐怕就要数取得特定的某个或某组元素的引用了.DOM定义了许多方式来选取元素,包括getElem ...
- 深入理解javascript选择器API系列第二篇——getElementsByClassName
× 目录 [1]使用 [2]classList [3]扩展 前面的话 既然有getElementById()和getElementsByTagName()方法,为什么没有getElementsByCl ...
- 深入理解javascript函数进阶系列第三篇——函数节流和函数防抖
前面的话 javascript中的函数大多数情况下都是由用户主动调用触发的,除非是函数本身的实现不合理,否则一般不会遇到跟性能相关的问题.但在一些少数情况下,函数的触发不是由用户直接控制的.在这些场景 ...
- javascript面向对象系列第三篇——实现继承的3种形式
× 目录 [1]原型继承 [2]伪类继承 [3]组合继承 前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.本文是javascript面向对象系列第三篇——实现继承的3种形式 [ ...
- 深入理解DOM事件类型系列第三篇——变动事件
× 目录 [1]删除节点 [2]插入节点 [3]特性节点[4]文本节点 前面的话 变动(mutation)事件能在DOM中的某一部分发生变化时给出提示,这类事件非常有用,但都只能使用DOM2级事件处理 ...
- 深入理解DOM事件机制系列第三篇——事件对象
× 目录 [1]获取 [2]事件类型 [3]事件目标[4]事件代理[5]事件冒泡[6]事件流[7]默认行为 前面的话 在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事 ...
- 深入理解脚本化CSS系列第三篇——脚本化CSS类
前面的话 在实际工作中,我们使用javascript操作CSS样式时,如果要改变大量样式,会使用脚本化CSS类的技术,本文将详细介绍脚本化CSS类 style 我们在改变元素的少部分样式时,一般会直接 ...
- 深入理解javascript函数进阶系列第四篇——惰性函数
前面的话 惰性函数表示函数执行的分支只会在函数第一次调用的时候执行,在第一次调用过程中,该函数会被覆盖为另一个按照合适方式执行的函数,这样任何对原函数的调用就不用再经过执行的分支了.本文将详细介绍惰性 ...
随机推荐
- Mysql - 查询之关联查询
查询这块是重中之重, 关系到系统反应时间. 项目做到后期, 都是要做性能测试和性能优化的, 优化的时候, 数据库这块是一个大头. sql格式: select 列名/* from 表名 where 条件 ...
- 闭区间套定理(Nested intervals theorem)
① ②这里用到了极限与不等关系 ③如果a≠b,那么便不会有$\lim _{n\rightarrow \infty }\left| I_n \right| =0$ ④如果还存在一点c在内,那么同样也不会 ...
- ASP.NET Aries JSAPI 文档说明:AR.Form、AR.Combobox
AR.Form 文档 1:对象或属性: 名称 类型 说明 data 属性 编辑页根据主键请求回来的数据 method 属性 用于获取数据的函数指向,默认值Get objName 属性 用于拦截form ...
- The Coroutine
关于Coroutine 说到coroutine就不的不说subroutine,也就是我们常用到的一般函数.调用一个函数开始执行,然后函数执行完成后就退出,再次调用的时候,再从头开始,调用之间是没有保存 ...
- React 其实比 MVVM 架构更加卡顿
React 号称通过引入 Virtual DOM 带来了性能的提升,而其实 React 之所以需要 Virtual DOM,是因为它的架构下,state 的变更是全量的,然后触发 render 返回全 ...
- Entity Framework 6 Recipes 2nd Edition(9-7)译->在WCF服务中序列化代理
9-7. 在WCF服务中序列化代理 问题 从一个查询里返回一个动态代理对象,想要把它序列为一个POCO(Plain-Old CLR Objects)对象. 实现基于POCO实体对象, 在运行时,EF会 ...
- Android开发学习之路-3DTouch效果模仿
3D Touch是什么效果的大家应该都知道了.什么?不知道,那也没办法呀,我也没有iPhone 6s演示给你看的. 本篇博客要做的效果图: 来个低质量动图: 这个动图效果不是很好,实际上模糊效果应该是 ...
- Linex 配置php服务器
此文是可以参考 楼主也不是系统管理员只是迫不得已所以自己才找的 大家可以参考 .... ..... 安装apache 安装mysql 安装PHP 测试服务器 php -v 查询php的版本 就这些了 ...
- postman使用
1.postman的下载:google首页左上角应用,点击后,如果没有下载postman,就在google商店搜索,点击右边按钮 2.下载后重新打开google首页,点击应用,可以看到已经下载过了,点 ...
- SQL 邮件配置篇
在我们运维工作中,经常要对备份,ETL等作业进行监控,这时我们需要用到SQL SERVER自带的邮件服务器,其原理,我在这么里不多说,直接来实战,下面是我对服务器配置源码,分享给大家,希望对大家有帮助 ...