美文网首页
JavaScript之contains()方法

JavaScript之contains()方法

作者: 执笔于情 | 来源:发表于2020-09-03 13:05 被阅读0次

    在研究级联选择器的时候,三级联动,发现了一个contains()方法,之前没有怎么接触过,随后在网上浏览,看到了司徒正美大佬的博客,里面有非常详细的介绍,摘录在此,谨记之。

    先附上大佬博客地址:
    作者:司徒正美(点此进入)
    链接:https://www.cnblogs.com/rubylouvre/archive/2009/10/14/1583523.html

    IE有许多好用的方法,后来都被其他浏览器抄袭了,比如这个contains()方法。如果A元素包含B元素,则返回true,否则false。唯一不支持这个方法的是IE的死对头firefox。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Dom contains()方法 by 司徒正美</title>
    </head>
    <body>
        <h2 style="text-align:center">contains方法</h2>
        <!-- 创建id为parent的div -->
        <div id="parent">
            <p>
                <!-- 创建id为child的strong -->
                <strong id="child">本例子会在火狐中会报错。</strong>
            </p>
        </div>
        <script type="text/javascript">
            window.onload = function(){
                var A = document.getElementById('parent'),
                B = document.getElementById('child');
                alert(A.contains(B)); // 判断A是否包含B 返回true
                alert(B.contains(A)); // 判断B是否包含A 返回false
            }
        </script>
    </body>
    </html>
    

    不过火狐支持compareDocumentPosition()方法,这是W3C制定的方法,标准浏览器都支持,不过实用性性很差,因此没有什么人用,推广不开来。它的使用形式与contains差不多,但返回的不是一个布尔值,而是一个很奇怪的数值,它是通过如下方式累加计算出来的:

    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 浏览器的私有使用

    firefox中compareDocumentPosition()方法

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Dom contains()方法 by 司徒正美</title>
    </head>
    <body>
        <h2 style="text-align:center">compareDocumentPosition方法</h2>
        <div id="parent">
        <p>
            <strong id="child" >本例子请在标准浏览器中运行。</strong>
        </p>
        </div>
        <script type="text/javascript">
            window.onload = function(){
                var A = document.getElementById('parent'),
                B = document.getElementById('child');
                // B与A不相连,B在A的后面,B被A包含 4+16 = 20
                alert(A.compareDocumentPosition(B));
                // A与B不相连,A在B的前面,A包含B 2+8 = 10
                alert(B.compareDocumentPosition(A));
            }
        </script>
    </body>
    </html>
    

    PPK给出如下解决方法。

    if (window.Node && Node.prototype && !Node.prototype.contains){
        Node.prototype.contains = function (arg) {
            return !!(this.compareDocumentPosition(arg) & 16)
        }
    }
    

    我搞出个更短的

    if(!!window.find){
        HTMLElement.prototype.contains = function(B){
            return this.compareDocumentPosition(B) - 19 > 0
        }
    }
    
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Dom contains()方法 by 司徒正美</title>
    </head>
    
    <body>
        <h2 style="text-align:center">contains方法</h2>
        <div id="parent">
            <p>
                <strong id="child">contains方法</strong>
            </p>
        </div>
        <script type="text/javascript">
            if (!!window.find) {
                HTMLElement.prototype.contains = function (B) {
                    return this.compareDocumentPosition(B) - 19 > 0
                }
            }
            window.onload = function () {
                var A = document.getElementById('parent'),
                    B = document.getElementById('child');
                alert(A.contains(B));
                alert(B.contains(A));
            }
        </script>
    </body>
    
    </html>
    
    var contains = function (root, el) {
           if (root.compareDocumentPosition) {
                return root === el || !!(root.compareDocumentPosition(el) & 16);
           }
           if (root.contains && el.nodeType === 1) {
               return root.contains(el) && root !== el;
           }
           while ((el = el.parentNode)) {
                 if (el === root) {
                     return true;
                 }
           }
           return false;
    }
    
    function contains(parentEl, el, container) {
           // 第一个节点是否包含第二个节点
          // contains 方法支持情况:chrome+ firefox9+ ie5+, 
          // opera9.64+(估计从9.0+),safari5.1.7+
           if (parentEl == el) {
                 return true;
           }
           if (!el || !el.nodeType || el.nodeType != 1) {
               return false;
           }
           if (parentEl.contains) {
               return parentEl.contains(el);
           }
           if (parentEl.compareDocumentPosition) {
               return !!(parentEl.compareDocumentPosition(el) & 16);
           }
           var prEl = el.parentNode;
           while (prEl && prEl != container) {
                 if (prEl == parentEl)
                     return true;
                 prEl = prEl.parentNode;
           }
           return false;
    }
    

    相关文章

      网友评论

          本文标题:JavaScript之contains()方法

          本文链接:https://www.haomeiwen.com/subject/mxynsktx.html