在研究级联选择器的时候,三级联动,发现了一个
contains()
方法,之前没有怎么接触过,随后在网上浏览,看到了司徒正美大佬的博客,里面有非常详细的介绍,摘录在此,谨记之。
先附上大佬博客地址:
作者:司徒正美(点此进入)
链接:https://www.cnblogs.com/rubylouvre/archive/2009/10/14/1583523.html
IE有许多好用的方法,后来都被其他浏览器抄袭了,比如这个
contains()
方法。如果A元素包含B元素,则返回true,否则false。唯一不支持这个方法的是IE的死对头firefox。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dom contains()方法 by 司徒正美</title>
</head>
<body>
<h2 style="text-align:center">contains方法</h2>
<!-- 创建id为parent的div -->
<div id="parent">
<p>
<!-- 创建id为child的strong -->
<strong id="child">本例子会在火狐中会报错。</strong>
</p>
</div>
<script type="text/javascript">
window.onload = function(){
var A = document.getElementById('parent'),
B = document.getElementById('child');
alert(A.contains(B)); // 判断A是否包含B 返回true
alert(B.contains(A)); // 判断B是否包含A 返回false
}
</script>
</body>
</html>
不过火狐支持
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 | 浏览器的私有使用 |
firefox中
compareDocumentPosition()
方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dom contains()方法 by 司徒正美</title>
</head>
<body>
<h2 style="text-align:center">compareDocumentPosition方法</h2>
<div id="parent">
<p>
<strong id="child" >本例子请在标准浏览器中运行。</strong>
</p>
</div>
<script type="text/javascript">
window.onload = function(){
var A = document.getElementById('parent'),
B = document.getElementById('child');
// B与A不相连,B在A的后面,B被A包含 4+16 = 20
alert(A.compareDocumentPosition(B));
// A与B不相连,A在B的前面,A包含B 2+8 = 10
alert(B.compareDocumentPosition(A));
}
</script>
</body>
</html>
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
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dom contains()方法 by 司徒正美</title>
</head>
<body>
<h2 style="text-align:center">contains方法</h2>
<div id="parent">
<p>
<strong id="child">contains方法</strong>
</p>
</div>
<script type="text/javascript">
if (!!window.find) {
HTMLElement.prototype.contains = function (B) {
return this.compareDocumentPosition(B) - 19 > 0
}
}
window.onload = function () {
var A = document.getElementById('parent'),
B = document.getElementById('child');
alert(A.contains(B));
alert(B.contains(A));
}
</script>
</body>
</html>
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;
}
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;
}