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

 更新时间:2010年02月04日 16:42:48   作者:  
一个很棒的 blog 文章,是 PPK 两年前写的,文章中解释了 contains() 和 compareDocumentPosition() 方法运行在他们各自的浏览器上。

从那起,我已经对这些方法做了大量的研究,并且已经在很多场合使用他们。在很多任务中,他们被证明是非常有用的(特别关于结构的抽象 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 都采取了一些主动落实这一方法。我依然期待看到更多的浏览器进入,以帮助向前推动

相关文章

  • 15 个 JavaScript Web UI 库

    15 个 JavaScript Web UI 库

    本文介绍了 15 个非常强大的 JavaScript Web UI 库,非常适合各种各种规模的富 Web 应用的开发。
    2010-05-05
  • 微信小程序表单验证功能完整实例

    微信小程序表单验证功能完整实例

    这篇文章主要介绍了微信小程序表单验证功能,结合完整实例形式分析了微信小程序完成表单验证功能所涉及的视图与逻辑操作技巧,需要的朋友可以参考下
    2017-12-12
  • 详解JavaScript的原型与原型链

    详解JavaScript的原型与原型链

    这篇文章主要为大家详细介绍了JavaScript原型与原型链,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • 使用layui监听器监听select下拉框,事件绑定不成功的解决方法

    使用layui监听器监听select下拉框,事件绑定不成功的解决方法

    今天小编就为大家分享一篇使用layui监听器监听select下拉框,事件绑定不成功的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • 微信小程序基于ColorUI构建皮皮虾短视频去水印组件

    微信小程序基于ColorUI构建皮皮虾短视频去水印组件

    这篇文章主要介绍了微信小程序-基于ColorUI构建皮皮虾短视频去水印组件,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-11-11
  • js变形金刚文字特效代码分享

    js变形金刚文字特效代码分享

    这篇文章主要介绍了js变形金刚文字特效,实现效果超酷,很立体,感兴趣的小伙伴们可以参考一下
    2015-08-08
  • JS实现网页每隔3秒弹出一次对话框的方法

    JS实现网页每隔3秒弹出一次对话框的方法

    这篇文章主要介绍了JS实现网页每隔3秒弹出一次对话框的方法,涉及JavaScript结合时间函数递归调用的相关技巧,非常简单,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • js 触发select onchange事件代码

    js 触发select onchange事件代码

    select 或text的onchange事件需要手动(通过键盘输入)改变select或text的值才能触发,本文为大家介绍下使用js触发select onchange事件
    2014-03-03
  • JS函数报错Uncaught ReferenceError: XX is not defined问题及解决

    JS函数报错Uncaught ReferenceError: XX is not

    这篇文章主要介绍了JS函数报错Uncaught ReferenceError: XX is not defined问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 微信小程序开发之改变data中数组或对象的某一属性值

    微信小程序开发之改变data中数组或对象的某一属性值

    本文通过案例给大家分析了微信小程序开发之改变data中数组或对象的某一属性值,本文通过实例代码相结合的形式给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-07-07

最新评论