Ruby's Louvre

每天学习一点点算法

导航

javascript contains方法

IE有许多好用的方法,后来都被其他浏览器抄袭了,比如这个contains方法。如果A元素包含B元素,则返回true,否则false。唯一不支持这个方法的是IE的死对头firefox。

不过火狐支持compareDocumentPosition() 方法,这是W3C制定的方法,标准浏览器都支持,不过实用性性很差,因此没有什么人用,推广不开来。它的使用形式与contains差不多,但返回的不是一个布尔值,而是一个很奇怪的数值,它是通过如下方式累加计算出来的:

Bits Number Meaning
0000000元素一致
0000011节点在不同的文档(或者一个在文档之外)
0000102节点 B 在节点 A 之前
0001004节点 A 在节点 B 之前
0010008节点 B 包含节点 A
01000016节点 A 包含节点 B
100000 32浏览器的私有使用

PPK给出如下解决方法。

 if (window.Node && Node.prototype && !Node.prototype.contains){
    Node.prototype.contains = function (arg) {
      return !!(this.compareDocumentPosition(arg) & 16)
    }
  }

我搞出个更短的:

  if(!!window.find){
    HTMLElement.prototype.contains = function(B){
      return this.compareDocumentPosition(B) - 19 > 0
    }
  }

   //2011.9.24 by 司徒正美 
           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;
            }
   //2013.1.24 by 司徒正美 
                function contains(parentEl, el, container) {
            // 第一个节点是否包含第二个节点
           //contains 方法支持情况:chrome+ firefox9+ ie5+, opera9.64+(估计从9.0+),safari5.1.7+
		if (parentEl == el) {
			return true;
		}
		if (!el || !el.nodeType || el.nodeType != 1) {
			return false;
		}
		if (parentEl.contains ) {
			return parentEl.contains(el);
		}
		if ( parentEl.compareDocumentPosition ) {
			return !!(parentEl.compareDocumentPosition(el) & 16);
		}
		var prEl = el.parentNode;
		while(prEl && prEl != container) {
			if (prEl == parentEl)
				return true;
			prEl = prEl.parentNode;
		}
		return false;
	}

posted on 2009-10-14 22:08  司徒正美  阅读(58171)  评论(25编辑  收藏  举报