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


Posted in Javascript onFebruary 04, 2010

从那起,我已经对这些方法做了大量的研究,并且已经在很多场合使用他们。在很多任务中,他们被证明是非常有用的(特别关于结构的抽象 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
000 0 元素一致
001 1 节点在不同的文档(或者一个在文档之外)
010 2 节点 B 在节点 A 之前
100 4 节点 A 在节点 B 之前
000 8 节点 B 包含节点 A
000 16 节点 A 包含节点 B
000 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 。如果你查看比特发生的变化,将增加你的理解。
100 (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 相关文章推荐
模仿jQuery each函数的链式调用
Jul 22 Javascript
JavaScript 入门基础知识 想学习js的朋友可以参考下
Dec 26 Javascript
JavaScript中“基本类型”之争小结
Jan 03 Javascript
JS操作iframe里的dom(实例讲解)
Jan 29 Javascript
jquery遍历checkbox介绍
Feb 21 Javascript
2则自己编写的jQuery特效分享
Feb 26 Javascript
检查表单元素的值是否为空的实例代码
Jun 16 Javascript
Bootstrap学习笔记之环境配置(1)
Dec 07 Javascript
vue 2.1.3 实时显示当前时间,每秒更新的方法
Sep 16 Javascript
layui实现数据分页功能
Jul 27 Javascript
解决vue-cli@3.xx安装不成功的问题及搭建ts-vue项目
Feb 09 Javascript
WebRTC记录音视频流(web技术分享)
Feb 24 Javascript
使用SyntaxHighlighter实现HTML高亮显示代码的方法
Feb 04 #Javascript
JavaScript学习笔记(十七)js 优化
Feb 04 #Javascript
jQuery生成asp.net服务器控件的代码
Feb 04 #Javascript
javascript两段代码,两个小技巧
Feb 04 #Javascript
JavaScript面向对象之静态与非静态类
Feb 03 #Javascript
JavaScript 学习笔记(十六) js事件
Feb 01 #Javascript
js左侧多级菜单动态的解决方案
Feb 01 #Javascript
You might like
不用mod_rewrite直接用php实现伪静态化页面代码
2008/10/04 PHP
php入门之连接mysql数据库的一个类
2012/04/21 PHP
php递归删除目录与文件的方法
2015/01/30 PHP
php判断linux下程序问题实例
2015/07/09 PHP
php+html5+ajax实现上传图片的方法
2016/05/14 PHP
浅谈PHP链表数据结构(单链表)
2016/06/08 PHP
js脚本学习 比较实用的基础
2006/09/07 Javascript
js实现数组去重、判断数组以及对象中的内容是否相同
2013/11/29 Javascript
jQuery学习总结之jQuery事件
2014/06/30 Javascript
jQuery读取XML文件内容的方法
2015/03/09 Javascript
jQuery遍历页面所有CheckBox查看是否被选中的方法
2015/04/14 Javascript
JQuery自适应窗口大小导航菜单附源码下载
2015/09/01 Javascript
分离与继承的思想实现图片上传后的预览功能:ImageUploadView
2016/04/07 Javascript
jQuery获取this当前对象子元素对象的方法
2016/11/29 Javascript
javascript 面向对象实战思想分享
2017/09/07 Javascript
浅析为什么a=&quot;abc&quot; 不等于 a=new String(&quot;abc&quot;)
2017/10/25 Javascript
代码详解javascript模块加载器
2018/03/04 Javascript
js/jquery遍历对象和数组的方法分析【forEach,map与each方法】
2019/02/27 jQuery
判断文字超过2行添加展开按钮,未超过则不显示,溢出部分显示省略号
2019/04/28 Javascript
微信小程序数据统计和错误统计的实现方法
2019/06/26 Javascript
Python过滤函数filter()使用自定义函数过滤序列实例
2014/08/26 Python
Python中用Decorator来简化元编程的教程
2015/04/13 Python
Python使用django搭建web开发环境
2017/06/09 Python
利用Python将时间或时间间隔转为ISO 8601格式方法示例
2017/09/05 Python
python 日期操作类代码
2018/05/05 Python
Python3实现的Mysql数据库操作封装类
2018/06/06 Python
Python实现变声器功能(萝莉音御姐音)
2019/12/05 Python
浅析Python3 pip换源问题
2020/01/06 Python
pytorch实现MNIST手写体识别
2020/02/14 Python
python查看矩阵的行列号以及维数方式
2020/05/22 Python
体育比赛口号
2014/06/09 职场文书
人生遥控器观后感
2015/06/11 职场文书
2016国庆节67周年红领巾广播稿
2015/12/18 职场文书
MySQL 数据类型选择原则
2021/05/27 MySQL
Win11如何设置右键单击显示所有选项?Win11右键单击显示所有选项设置教程
2022/04/08 数码科技
小喇叭开始广播了! 四十多年前珍贵老照片
2022/05/09 无线电