以前写弹出层的时候,有用过,就是查询 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差不多,但返回的不是 一个布尔值,而是一个很奇怪的数值,它是通过如下方式累加计算出来的:

   

BitsNumberMeaning
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;
         }
 posted on 2012-06-20 11:14 落叶满长沙 阅读(...) 评论(...) 编辑 收藏