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 常用方法经典总结
Jan 28 Javascript
js模拟类继承小例子
Jul 17 Javascript
IE下js调试工具Companion.JS
Oct 15 Javascript
javascript实现数字+字母验证码的简单实例
Feb 10 Javascript
正则验证小数点后面只能有两位数的方法
Feb 28 Javascript
jQuery插件FusionCharts绘制2D柱状图和折线图的组合图效果示例【附demo源码】
Apr 10 jQuery
浅析JavaScript中的平稳退化(graceful degradation)
Jul 24 Javascript
Angular 4.x+Ionic3踩坑之Ionic3.x pop反向传值详解
Mar 13 Javascript
学习React中ref的两个demo示例
Aug 14 Javascript
node.js实现简单的压缩/解压缩功能示例
Nov 05 Javascript
ES6 Iterator遍历器原理,应用场景及相关常用知识拓展详解
Feb 15 Javascript
vue-cli3 热更新配置操作
Sep 18 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
简单示例AJAX结合PHP代码实现登录效果代码
2008/07/25 PHP
php rsa 加密,解密,签名,验签详解
2016/12/06 PHP
Yii框架参数化查询中IN查询只能查询一个的解决方法
2017/05/20 PHP
PHP DB 数据库连接类定义与用法示例
2019/03/11 PHP
javascript new 需不需要继续使用
2009/07/02 Javascript
浅析jquery某一元素重复绑定的问题
2014/01/03 Javascript
ExtJS 4.2 Grid组件单元格合并的方法
2016/10/12 Javascript
一篇看懂vuejs的状态管理神器 vuex状态管理模式
2017/04/20 Javascript
vue 虚拟dom的patch源码分析
2018/03/01 Javascript
通过函数作用域和块级作用域看javascript的作用域链
2018/08/05 Javascript
JS获取当前时间的年月日时分秒及时间的格式化的方法
2019/12/18 Javascript
vue-resourc发起异步请求的方法
2020/02/11 Javascript
Electron 打包问题:electron-builder 下载各种依赖出错(推荐)
2020/07/09 Javascript
Python中的__SLOTS__属性使用示例
2015/02/18 Python
python通过get,post方式发送http请求和接收http响应的方法
2015/05/26 Python
Python3实现爬取简书首页文章标题和文章链接的方法【测试可用】
2018/12/11 Python
pycharm 实现显示project 选项卡的方法
2019/01/17 Python
使用pyshp包进行shapefile文件修改的例子
2019/12/06 Python
Python+PyQt5实现灭霸响指功能
2020/05/25 Python
python3.9和pycharm的安装教程并创建简单项目的步骤
2021/02/03 Python
html5记忆翻牌游戏实现思路及代码
2013/07/25 HTML / CSS
惠普美国官方商店:HP Official Store
2016/08/28 全球购物
印度第一网上礼品店:IGP.com
2020/02/06 全球购物
Super-Pharm波兰:药房和香水在一个地方
2020/08/18 全球购物
求职毕业生自荐书
2014/02/08 职场文书
渡河少年教学反思
2014/02/12 职场文书
《在山的那边》教学反思
2014/02/23 职场文书
《高尔基和他的儿子》教学反思
2014/04/09 职场文书
《假如》教学反思
2014/04/17 职场文书
工商局所长四风自我剖析及整改措施
2014/10/26 职场文书
2014年设计师工作总结
2014/11/25 职场文书
先进教师事迹材料
2014/12/16 职场文书
保研推荐信格式
2015/03/25 职场文书
广播体操比赛主持词
2015/06/29 职场文书
学习《中小学教师职业道德规范》心得体会
2016/01/18 职场文书
基于Python编写一个监控CPU的应用系统
2022/06/25 Python