contains和compareDocumentPosition 方法来确定是否HTML节点间的关系


Posted in Javascript onSeptember 13, 2011

从那起,我已经对这些方法做了大量的研究,并且已经在很多场合使用他们。在很多任务中,他们被证明是非常有用的(特别关于结构的抽象 DOM 选择器)。
1、DOMElement.contains(DOMNode)
这个方法起先用在 IE ,用来确定 DOM Node 是否包含在另一个 DOM Element 中。
当尝试优化 CSS 选择器遍历(像:“#id1 #id2”),这个方法很有用。你可以通过 getElementById 得到元素,然后使用 .contains() 确定 #id1 实际上是否包含 #id2。
注意点:如果 DOM Node 和 DOM Element 相一致,.contains() 将返回 true ,虽然,一个元素不能包含自己。
这里有一个简单的执行包装,可以运行在:Internet Explorer, Firefox, Opera, and Safari。
function contains(a, b) {
return a.contains ? a != b && a.contains(b) : !!(a.compareDocumentPosition(arg) & 16);
}

2、NodeA.compareDocumentPosition(NodeB)
这个方法是 DOM Level 3 specification 的一部分,允许你确定 2 个 DOM Node 之间的相互位置。这个方法比 .contains() 强大。这个方法的一个可能应用是排序 DOM Node 成一个详细精确的顺序。
使用这个方法你可以确定关于一个元素位置的一连串的信息。所有的这些信息将返回一个比特码(Bit,比特,亦称二进制位)。
对于那些,人们知之甚少。比特码是将多重数据存储为一个简单的数字(译者注:0 或 1)。你最终打开 / 关闭个别数目(译者注:打开/关闭对应 0 /1),将给你一个最终的结果。
这里是从 NodeA.compareDocumentPosition(NodeB) 返回的结果,包含你可以得到的信息。
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 浏览器的私有使用

现在,这意味着一个可能的结果类似于:

<div id="a"> 
<div id="b"></div> 
</div> 
<script> 
alert( document.getElementById("a").compareDocumentPosition(document.getElementById("b")) == 20); 
</script>

一旦一个节点 A 包含另一个节点 B,包含 B(+16) 且在 B 之前(+4),则最后的结果是数字 20 。如果你查看比特发生的变化,将增加你的理解。
000100 (4) + 010000 (16) = 010100 (20)
这个,毫无疑问,有助于理解单个最混乱的 DOM API 方法。当然,他的价值当之无愧的。
现在,DOMNode.compareDocumentPosition 在 Firefox 和 Opera 中是可用的。然而,有一些技巧,我们可以用来在 IE 中执行他。
// Compare Position - MIT Licensed, John Resig 
function comparePosition(a, b){ 
return a.compareDocumentPosition ? 
a.compareDocumentPosition(b) : 
a.contains ? 
( a != b && a.contains(b) && 16 ) + 
( a != b && b.contains(a) && 8 ) + 
( a.sourceIndex >= 0 && b.sourceIndex >= 0 ? 
(a.sourceIndex < b.sourceIndex && 4 ) + 
(a.sourceIndex > b.sourceIndex && 2 ) : 
1 ) : 
0; 
}

IE 提供给我们一些可以使用的方法和属性。开始,使用 .contains() 方法(如我们前面所讨论的),以便给我们包含(+16)或者被包含(+8)的结果。IE 还有一个 .sourceIndex 属性在所有的 DOM Element 对应着元素在文档中的位置,例如:document.documentElement.sourceIndex == 0。因为我们有这个信息,我们可以完成两个 compareDocumentPosition 难题:在前面(+2)和在后面(+4)。另外,如果一个元素不在当前的文档,.sourceIndex 将等于 -1,这个给我们另外一个回答(+1)。最后,通过这个过程的推断,我们可以确定如果一个元素等于他本身,返回一个空的比特码(+0)。
这个函数可以在 Internet Explorer、Firefox 和 Opera 中运行。但在 Safari 中却有残缺功能(因为他只有 contains() 方法,而没有 .sourceIndex 属性。我们只能得到 包含(+16),被包含(+8),其他的所有结果都将返回(+1)代表一个断开)。
PPK 提供了一个关于通过创建一个 getElementsByTagNames 方法使新功能可以被使用的很棒的例子。让我们改编他到我们的新方法中:
// Original by PPK quirksmode.org 
function getElementsByTagNames(list, elem) { 
elem = elem || document; 
var tagNames = list.split(','), results = []; 
for ( var i = 0; i < tagNames.length; i++ ) { 
var tags = elem.getElementsByTagName( tagNames[i] ); 
for ( var j = 0; j < tags.length; j++ ) 
results.push( tags[j] ); 
} 
return results.sort(function(a, b){ 
return 3 - (comparePosition(a, b) & 6); 
}); 
}

我们现在可以使用他来按次序构建一个站点的目录:
getElementsByTagNames("h1, h2, h3");
虽然 Firefox 和 Opera 都采取了一些主动落实这一方法。我依然期待看到更多的浏览器进入,以帮助向前推动
Javascript 相关文章推荐
AJAX架构之Dojo篇
Apr 10 Javascript
IE 上下滚动展示模仿Marquee机制
Dec 20 Javascript
js原生跨域_用script标签的简单实现
Sep 24 Javascript
JS实现商品筛选功能
Aug 19 Javascript
深入浅析Vue中的 computed 和 watch
Jun 06 Javascript
详解Vue一个案例引发「内容分发slot」的最全总结
Dec 02 Javascript
关于微信小程序登录的那些事
Jan 08 Javascript
解决vue单页面应用中动态修改title问题
Jun 09 Javascript
微信小程序如何修改radio和checkbox的默认样式和图标
Jul 24 Javascript
基于JS实现简单滑块拼图游戏
Oct 12 Javascript
vue获取data数据改变前后的值方法
Nov 07 Javascript
js将URL网址转为16进制加密与解密函数
Mar 04 Javascript
jQuery中使用了document和window哪些属性和方法小结
Sep 13 #Javascript
从jQuery.camelCase()学习string.replace() 函数学习
Sep 13 #Javascript
各情景下元素宽高的获取实现代码
Sep 13 #Javascript
JS字符串函数扩展代码
Sep 13 #Javascript
Javascript学习笔记 delete运算符
Sep 13 #Javascript
Webkit的跨域安全问题说明
Sep 13 #Javascript
Array, Array Constructor, for in loop, typeof, instanceOf
Sep 13 #Javascript
You might like
snoopy PHP版的网络客户端提供本地下载
2008/04/15 PHP
PHP操作mysql数据库分表的方法
2016/06/09 PHP
php curl上传、下载、https登陆实现代码
2017/07/23 PHP
php文件后缀不强制为.php的实操方法
2019/09/18 PHP
php使用gearman进行任务分发操作实例详解
2020/02/26 PHP
JavaScript实现快速排序(自已编写)
2012/12/19 Javascript
通过JavaScript使Div居中并随网页大小改变而改变
2013/06/24 Javascript
一个非常全面的javascript URL解析函数和分段URL解析方法
2014/04/12 Javascript
jQuery-1.9.1源码分析系列(十)事件系统之事件包装
2015/11/20 Javascript
JS触发服务器控件的单击事件(详解)
2016/08/06 Javascript
jQuery自定义组件(导入组件)
2016/11/08 Javascript
javascript中this关键字详解
2016/12/12 Javascript
JS实现图片垂直居中显示小结
2016/12/13 Javascript
Bootstrap的Carousel配合dropload.js实现移动端滑动切换图片
2017/03/10 Javascript
在vue中获取微信支付code及code被占用问题的解决方法
2019/04/16 Javascript
vue循环数组改变点击文字的颜色
2019/10/14 Javascript
基于redis的小程序登录实现方法流程分析
2020/05/25 Javascript
js实现贪吃蛇游戏 canvas绘制地图
2020/09/09 Javascript
[27:02]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS LGD第三场
2014/05/24 DOTA
使用Python解析JSON数据的基本方法
2015/10/15 Python
Python将多个excel表格合并为一个表格
2021/02/22 Python
TensorFlow实现卷积神经网络CNN
2018/03/09 Python
Python代码缩进和测试模块示例详解
2018/05/07 Python
python实现图片彩色转化为素描
2019/01/15 Python
python基础梳理(一)(推荐)
2019/04/06 Python
Python实现的ftp服务器功能详解【附源码下载】
2019/06/26 Python
python super的使用方法及实例详解
2019/09/25 Python
Python迭代器iterator生成器generator使用解析
2019/10/24 Python
ORACLE十问
2015/04/20 面试题
个人求职信范文分享
2013/12/13 职场文书
幼儿园教师个人反思
2014/01/30 职场文书
中国梦演讲稿教师篇
2014/04/23 职场文书
实习计划书范文
2015/01/16 职场文书
学校财务管理制度
2015/08/04 职场文书
创业计划书之儿童理发店
2019/09/27 职场文书
用Python实现一个打字速度测试工具来测试你的手速
2021/05/28 Python