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 相关文章推荐
(推荐一个超好的JS函数库)S.Sams Lifexperience ScriptClassLib
Apr 29 Javascript
用jQuery实现一些导航条切换,显示隐藏的实例代码
Jun 08 Javascript
获取中文字符串的实际长度代码
Jun 05 Javascript
js实现select跳转菜单新窗口效果代码分享(超简单)
Aug 21 Javascript
js判断手机访问或者PC的几个例子(常用于手机跳转)
Dec 15 Javascript
JS实现颜色动态淡化效果
Mar 06 Javascript
ES6模块化的import和export用法方法总结
Aug 08 Javascript
移动端(微信等使用vConsole调试console的方法
Mar 05 Javascript
Vue实现滑动拼图验证码功能
Sep 15 Javascript
使用Vue调取接口,并渲染数据的示例代码
Oct 28 Javascript
基于JavaScript实现简单抽奖功能代码实例
Oct 20 Javascript
JavaScript实现五子棋小游戏
Oct 26 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
使用Apache的rewrite技术
2006/06/22 PHP
初学CAKEPHP 基础教程
2009/11/02 PHP
PHP项目开发中最常用的自定义函数整理
2010/12/02 PHP
解析MySql与Java的时间类型
2013/06/22 PHP
ThinkPHP之getField详解
2014/06/20 PHP
PHP CodeIgniter框架的工作原理研究
2015/03/30 PHP
PHP 微信支付类 demo
2015/11/30 PHP
PHP获取指定时间段之间的 年,月,天,时,分,秒
2016/06/05 PHP
tp5(thinkPHP5框架)使用DB实现批量删除功能示例
2019/05/28 PHP
JavaScript全局函数使用简单说明
2011/03/11 Javascript
js 显示base64编码的二进制流网页图片
2014/04/04 Javascript
高性能JavaScript模板引擎实现原理详解
2015/02/05 Javascript
jquery不常用方法汇总
2015/07/26 Javascript
BootStrap3使用错误记录及解决办法
2016/12/22 Javascript
关于Javascript中document.cookie的使用
2017/03/08 Javascript
Angular 4.x+Ionic3踩坑之Ionic 3.x界面传值详解
2018/03/13 Javascript
Vue 项目代理设置的优化
2018/04/17 Javascript
JavaScript设计模式之责任链模式实例分析
2019/01/16 Javascript
jquery实现轮播图特效
2020/04/12 jQuery
vue和小程序项目中使用iconfont的方法
2020/05/19 Javascript
[03:21]辉夜杯主赛事 12月25日TOP5
2015/12/26 DOTA
布同 Python中文问题解决方法(总结了多位前人经验,初学者必看)
2011/03/13 Python
Python利用ElementTree模块处理XML的方法详解
2017/08/31 Python
python利用paramiko连接远程服务器执行命令的方法
2017/10/16 Python
django之跨表查询及添加记录的示例代码
2018/10/16 Python
Python 实现王者荣耀中的敏感词过滤示例
2019/01/21 Python
使用python 计算百分位数实现数据分箱代码
2020/03/03 Python
python实现取余操作的简单实例
2020/08/16 Python
HTML5 canvas绘制的玫瑰花效果
2014/05/29 HTML / CSS
Marlies Dekkers内衣法国官方网上商店:国际知名的荷兰内衣品牌
2019/03/18 全球购物
Wilson体育用品官网:美国著名运动器材品牌
2019/05/12 全球购物
Web Service面试题:如何搭建Axis2的开发环境
2012/06/20 面试题
奥巴马竞选演讲稿
2014/05/15 职场文书
转让协议书
2015/01/27 职场文书
介绍信范文大全
2015/05/07 职场文书
优质护理服务心得体会
2016/01/22 职场文书