以前写弹出层的时候,有用过,就是查询 a , b 两元素是否有包含关系。
回顾记录一下。
比如一个弹出层,a 然后 点击除开a以外的任何地方就要把a给关闭了。
那么,首先应该是给body添加一个click的处理函数用来接收事件的冒泡。
然后 在这个处理函数内
event = event? event: window.event
var obj = event.srcElement ? event.srcElement:event.target;
这个obj 就是你点击的那个对象了
然后,然后怎么判断?obj 就是a 以外的地方呢?
两种方法,
1,判断你的层在obj的parentNode
的链里面,,或者就是obj本身,,
这是最原始的土鳖方法
function
isParent (obj,parentObj){
while
(obj != undefined && obj !=
null
&& obj.tagName.toUpperCase() !=
'BODY'
){
if
(obj == parentObj){
return ture;
}
obj = obj.parentNode;
}
}
2,有个方法可以直接判断,但是要找做兼容
IE有许多好用的方法, 比如这个contains方法。如果A元素包含B元素,则返回true,否则false。但是很遗憾,这个是ie only。
不过有个好消息就是,
火狐支持compareDocumentPosition() 方法,这是W3C制定的方法,标准浏览器都支持。它的使用形式与contains差不多,但返回的不是 一个布尔值,而是一个很奇怪的数值,它是通过如下方式累加计算出来的:
Bits | Number | Meaning |
---|---|---|
000000 | 0 | 元素一致 |
000001 | 1 | 节点在不同的文档(或者一个在文档之外) |
000010 | 2 | 节点 B 在节点 A 之前 |
000100 | 4 | 节点 A 在节点 B 之前 |
001000 | 8 | 节点 B 包含节点 A |
010000 | 16 | 节点 A 包含节点 B |
100000 | 32 | 浏览器的私有使用 |
所以,ppk提出给非ie做原型的扩展
if
(window.Node && Node.prototype && !Node.prototype.contains){
Node.prototype.contains =
function
(arg) {
return
!!(
this
.compareDocumentPosition(arg) & 16)
}
}
var
contains =
function
(root , el) {
if
(root.compareDocumentPosition)
return
root === el || !!(root.compareDocumentPosition(el) & 16);
if
(root.contains && el.nodeType === 1){
return
root.contains(el) && root !== el;
}
while
((el = el.parentNode))
if
(el === root)
return
true
;
return
false
;
}