IE有許多好用的方法,後來都被其他瀏覽器抄襲了,比如這個contains方法。如果A元素包含B元素,則返回true,否則false。唯一不支援這個方法的是IE的死對頭firefox。
<br /><!doctype html><br /><title>dom contains 方法 by 司徒正美</title><br /><meta charset="utf-8"/><br /><meta name="keywords" content="dom contains 方法 by 司徒正美" /><br /><meta name="description" content="dom contains 方法 by 司徒正美" /></p><p><script type="text/javascript"><br /> window.onload = function(){<br /> var A = document.getElementById('parent'),<br /> B = document.getElementById('child');<br /> alert(A.contains(B));<br /> alert(B.contains(A));<br /> }<br /></script><br /><h2 style="text-align:center">contains方法</h2></p><p><div id="parent"><br /> <p><br /> <strong id="child" >本例子會在Firefox中會報錯。</strong><br /> </p><br /></div><br />
運行代碼
不過Firefox支援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 |
瀏覽器的私人使用 |
<br /><!doctype html><br /><title>dom contains 方法 by 司徒正美</title><br /><meta charset="utf-8"/><br /><meta name="keywords" content="dom contains方法 by 司徒正美" /><br /><meta name="description" content="dom contains方法 by 司徒正美" /></p><p><script type="text/javascript"></p><p> window.onload = function(){<br /> var A = document.getElementById('parent'),<br /> B = document.getElementById('child');<br /> alert(A.compareDocumentPosition(B));//B與A不相連,B在A的後面,B被A包含 4+16 = 20<br /> alert(B.compareDocumentPosition(A));//A與B不相連,A在B的前面,A包含B 2+8 = 10<br /> }<br /></script><br /><h2 style="text-align:center">compareDocumentPosition方法</h2></p><p><div id="parent"><br /> <p><br /> <strong id="child" >本例子請在標準瀏覽器中運行。</strong><br /> </p><br /></div><br />
運行代碼
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 } }
<br /><!doctype html><br /><title>dom contains 方法 by 司徒正美</title><br /><meta charset="utf-8"/><br /><meta name="keywords" content="dom contains方法 by 司徒正美" /><br /><meta name="description" content="dom contains方法 by 司徒正美" /></p><p><script type="text/javascript"><br /> if(!!window.find){<br /> HTMLElement.prototype.contains = function(B){<br /> return this.compareDocumentPosition(B) - 19 > 0<br /> }<br /> }<br /> window.onload = function(){<br /> var A = document.getElementById('parent'),<br /> B = document.getElementById('child');<br /> alert(A.contains(B));<br /> alert(B.contains(A));<br /> }<br /></script><br /><h2 style="text-align:center">contains方法</h2></p><p><div id="parent"><br /> <p><br /> <strong id="child" >contains方法</strong><br /> </p><br /></div><br />
運行代碼
//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 司徒正美 var contains = function(a, b, itself){ // 第一個節點是否包含第二個節點 //contains 方法支援情況:chrome+ firefox9+ ie5+, opera9.64+(估計從9.0+),safari5.1.7+ if(itself && a == b){ return true } if(a.contains){ if(a.nodeType === 9 ) return true; return a.contains(b); }else if(a.compareDocumentPosition){ return !!(a.compareDocumentPosition(b) & 16); } while ((b = b.parentNode)) if (a === b) return true; return false; },