matchesSelector用来匹配dom元素是否匹配某css selector。它为一些高级方法的实现提供了基础支持,比如事件代理,parent,
closest等。
W3C在2006年就提出了该方法草案,Firefox和Safari相继实现,比如
?
1
2
3
4
5
6
|
<div id= "wraper"
class = "item" ></div>
<script>
wraper.mozMatchesSelector( ‘div‘ ) // true 标签选择器
wraper.mozMatchesSelector( ‘#wraper‘ ) // true id选择器
wraper.mozMatchesSelector( ‘.item‘ ) // true 类选择器
</script>
|
目前除IE6-IE8,Firefox/Chrome/Safari/Opera/IE 的最新版本均已实现,但方法都带上了各自的前缀
Chrome/Safari
Firefox
IE9+
可以用特性监测来获取一个统一接口API。如下
?
1
2
3
4
|
var
matchesSelector = function () {
var
body = document.body
return
body.webkitMatchesSelector || body.msMatchesSelector || body.mozMatchesSelector || body.oMatchesSelector
}()
|
有两个细节
1. 优先使用body.webkitMatchesSelector
webkit内核占有率最高,尤其国内国产浏览器的高速引擎是webkit
2. 这里没有优选获取body.matchesSelector,是因为该方法迄今尚未标准化
3. 2013年2月Opera放弃Presto转向Webkit,因此把body.oMatchesSelector放在了最后以兼容老版本的Opera
对于低版本的IE,如何实现该方法吗? 首先需要实现一个基本的CSS选择器,这里提供了一个常用选择器(id,class,tagName,attribute)的实现。
两种情况
1. 对于已经存在于页面里的DOM元素
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function
matches(el, selector) {
var
parent = el.parentNode
var
match = query(selector, parent)
var
len = match.length
if
(len) {
while
(len--) {
if
(match[len] == el) {
return
true
}
}
return
false
} else
{
return
false
}
}
|
存在于页面的DOM元素,必定有parentNode,紧接着在父节点里查找指定的selector,如果不存在返回false,如果存在还有过滤下,如果匹配的元素和传入的el是同一个元素则返回true。
2. 对于动态创建的元素,尚未添加到页面中
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
function
matches(el, selector) {
var
tempParent = document.createElement( ‘div‘ )
tempParent.appendChild(el)
match = query(selector, tempParent)
tempParent.removeChild(el)
return
!!match.length
}
var
pp = document.createElement( ‘p‘ )
pp.id = ‘pp‘
pp.className = ‘pp1‘
pp.setAttribute( ‘data-info‘ , ‘Jack‘ )
pp.innerHTML = ‘test‘
matches(pp, ‘p‘ ) // true
matches(pp, ‘#pp‘ ) // true
matches(pp, ‘.pp1‘ ) // true
matches(pp, ‘[data-info=jack]‘ ) // true
|
此时该元素师没有父元素的,这里创建了一个临时的父元素,添加子元素后再把它删掉。剩余思路同上。
两种情况合并一起就完成了对IE9-版本浏览器的支持
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
function
matches(el, selector) {
var
parent = el.parentNode
var
match = query(selector, parent)
var
len = match.length
if
(parent) {
if
(len) {
while
(len--) {
if
(match[len] == el) {
return
true
}
}
return
false
} else
{
return
false
}
} else
{
var
parent = document.createElement( ‘div‘ )
parent.appendChild(el)
match = query(selector, parent)
parent.removeChild(el)
return
!!match.length
}
}
|
最后是一个完成版本
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
var
matchesSelector = function () {
var
body = document.body
var
w3cMatches = body.webkitMatchesSelector || body.msMatchesSelector || body.mozMatchesSelector || body.oMatchesSelector
function
matches(el, selector) {
return
w3cMatches.call(el, selector)
}
function
lowIEMatches(el, selector) {
var
parent = el.parentNode
var
match = query(selector, parent)
var
len = match.length
if
(parent) {
if
(len) {
while
(len--) {
if
(match[len] == el) {
return
true
}
}
return
false
} else
{
return
false
}
} else
{
var
parent = document.createElement( ‘div‘ )
parent.appendChild(el)
match = query(selector, parent)
parent.removeChild(el)
return
!!match.length
}
}
return
w3cMatches ? matches : lowIEMatches
}()
|
相关:
http://dev.w3.org/2006/webapi/selectors-api2/#matchtesting
https://developer.mozilla.org/zh-CN/docs/Web/API/Element.matches
http://msdn.microsoft.com/en-us/library/ie/ff975201(v=vs.85).aspx
matchesSelector及低版本IE中对该方法的实现,布布扣,bubuko.com
时间: 2024-10-13 12:18:42