H5使用Selectors API简化选取操作

随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)

一、介绍

先看看以前查找元素的js方法

尽管DOM作为API已经非常完善了,但是为了实现更多的功能,DOM仍然进行了扩展,其中一个重要的扩展就是对选择器API的扩展。有了新的 Selectors API后,可以用更精确的方式来指定希望获取的元素,而不必用标准的DOM方式去遍历。 Selectors API与现在CSS选择规则一样,通过它可以查找一个或者多个元素。新的查询方法有:

querySelectorAll()、querySelector()和matchesSelector()

通过CSS选择符查询DOM文档取得元素引用的功能变成了原生的API,解析和树查询操作在浏览器内部通过编译后的代码来完成,极大地改善了性能。

还可以为 Selectors API函数同时指定多个选择规则,如

		//选择文档中类名为oneClass或者twoClass的第一个元素
		var x=document.querySelector(".oneClass","twoClass");

而对于querySelectorAll()来说,满足规则的任何一个元素都会被返回,多条规则用逗号分隔。下面看示例

二、示例

1、querySelector()

querySelector()方法接收一个CSS选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null。该方法既可用于文档document类型,也可用于元素element类型。

[注意]IE7-浏览器不支持

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试Selectors API</title>
</head>
<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>
</html>

页面结果如下

2、querySelectorAll() 

querySelectorAll()接收一个CSS选择符,返回一个类数组对象NodeList的实例。具体来说,返回的值实际上是带有所有属性和方法的NodeList,而其底层实现则类似于一组元素的快照,而非不断对文档进行搜索的动态查询。这样实现可以避免使用NodeList对象通常会引起的大多数性能问题。只要传给querySelectorAll()方法的CSS选择符有效,该方法都会返回一个NodeList对象,而不管找到多少匹配的元素。没有匹配元素时,返回空的类数组对象,而不是null

[注意]IE7-浏览器不支持

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试Selectors API</title>
</head>
<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>
</html>

运行结果如下:

 3、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()方法。所以兼容写法为:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试Selectors API</title>
</head>
<body id="test">
	<script>
		console.log(matchesSelector(document.body, '#test'));//true
		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);
			}
		}
	</script>
</body>
</html>

三、优劣对比

1、非实时

新增方法虽然方便了许多但是也有些缺陷,与getElementById()和getElementsByTagName()方法不同,querySelector()和querySelectorAll()方法得到的类数组对象是非动态实时的

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试Selectors API</title>
</head>
<body id="test">
	<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>
</body>
</html>

2、参数缺陷

selector类方法在元素上调用时,指定的选择器仍然在整个文档中进行匹配,然后过滤出结果集,以便它只包含指定元素的后代元素。这看起来是违反常规的,因为它意味着选择器字符串能包含元素的祖先而不仅仅是所匹配的元素 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试Selectors API</title>
</head>
<body id="test">
	<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>
</body>
</html>

按照正常理解,控制台应该返回空的类数组对象,因为id为container的div元素的子元素中,不存在div元素嵌套的情况

但是,该方法实际返回[div div]。这是因为参数中的选择器包含了元素的祖先

所以,如果出现后代选择器,为了防止该问题,可以在参数中显式地添加当前元素的选择器

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试Selectors API</title>
</head>
<body id="test">
	<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>
</body>
</html>

虽然存在着非实时和参数缺陷的问题,但是瑕不掩瑜,selector类方法的出现极大地简化了查找元素的繁琐操作。而且,它们支持IE8浏览器 

参考链接:深入理解javascript选择器API系列第三篇——HTML5新增的3种selector方法 - 小火柴的蓝色理想 - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

u010142437

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值