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 相关文章推荐
点击文章内容处弹出页面代码
Oct 01 Javascript
jQuery最佳实践完整篇
Aug 20 Javascript
jquery事件机制扩展插件 jquery鼠标右键事件
Dec 21 Javascript
写自已的js类库需要的核心代码
Jul 16 Javascript
利用jq让你的div居中的好方法分享
Nov 21 Javascript
JS,Jquery获取select,dropdownlist,checkbox下拉列表框的值(示例代码)
Jan 11 Javascript
纯css+js写的一个简单的tab标签页带样式
Jan 28 Javascript
分享纯手写漂亮的表单验证
Nov 19 Javascript
jQuery Validation Engine验证控件调用外部函数验证的方法
Jan 18 Javascript
微信小程序新增的拖动组件movable-view使用教程
May 20 Javascript
jQuery完成表单验证的实例代码(纯代码)
Sep 30 jQuery
jquery.param()实现数组或对象的序列化方法
Oct 08 jQuery
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
php 上一篇,下一篇文章实现代码与原理说明
2010/05/09 PHP
POSIX 风格和兼容 Perl 风格两种正则表达式主要函数的类比(preg_match, preg_replace, ereg, ereg_replace)
2010/10/12 PHP
PHP图片处理之图片旋转和图片翻转实例
2014/11/19 PHP
php在线解压ZIP文件的方法
2014/12/30 PHP
php银联网页支付实现方法
2015/03/04 PHP
[原创]php获取数组中键值最大数组项的索引值
2015/03/17 PHP
详解WordPress中过滤链接与过滤SQL语句的方法
2015/12/18 PHP
php获取服务器操作系统相关信息的方法
2016/10/08 PHP
PHP正则匹配日期和时间(时间戳转换)的实例代码
2016/12/14 PHP
PHP 实现文件压缩解压操作的方法
2019/06/14 PHP
基于jQuery的星级评分插件
2011/08/12 Javascript
js Object2String方便查看js对象内容
2014/11/24 Javascript
javascript包装对象实例分析
2015/03/27 Javascript
jQuery实现的经典滑动门效果
2015/09/22 Javascript
js读取并解析JSON类型数据的方法
2015/11/14 Javascript
jQuery基于toggle实现click触发DIV的显示与隐藏问题分析
2016/06/12 Javascript
js中遍历Map对象的方法
2016/07/27 Javascript
JavaScript蒙板(model)功能的简单实现代码
2016/08/04 Javascript
微信小程序 vidao实现视频播放和弹幕的功能
2016/11/02 Javascript
原生Aajax 和jQuery Ajax 写法个人总结
2017/03/24 jQuery
Angular2中select用法之设置默认值与事件详解
2017/05/07 Javascript
js原生实现移动端手指滑动轮播图效果的示例
2018/01/02 Javascript
mac上配置Android环境变量的方法
2018/07/08 Javascript
基于vue中keep-alive缓存问题的解决方法
2018/09/21 Javascript
Vue循环遍历选项赋值到对应控件的实现方法
2020/06/22 Javascript
[01:10:49]Secret vs VGJ.S 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
python基础教程之获取本机ip数据包示例
2014/02/10 Python
详细讲解用Python发送SMTP邮件的教程
2015/04/29 Python
Python中turtle作图示例
2017/11/15 Python
Python import与from import使用及区别介绍
2018/09/06 Python
python利用JMeter测试Tornado的多线程
2020/01/12 Python
中国电视购物:快乐购
2017/02/04 全球购物
网络维护管理员的自我评价分享
2013/11/11 职场文书
离婚协议书范文
2015/01/26 职场文书
2015安全保卫工作总结
2015/04/25 职场文书
Win11安装升级时提示“该电脑必须支持安全启动”
2022/04/19 数码科技