• 第十一课:js操作选择器的通用函数


    1.判断文档是否是XML文档

    var isXML = function(elem){

      var documentElement = elem && (elem.ownerDocument || elem).documentElement;  

      return documentElement ? documentElement.nodeName !=="HTML" : false;

    }

    看懂以上代码,需要先了解这两个的区别:

    ownerDocument返回的是某个元素的根节点文档对象(即document对象)
    而documentElement 返回的就是文档根节点。(html文档就是html,xml文档就是最外面的节点元素)

    因此,如果传入函数中的元素属于html文档,那么documentElement = document.documentElement = html,因此html元素的nodeName == "HTML" (会默认变成大写)。

    如果传入的的元素是XML文档,那么documentElement = document.documentElement = 最外面的节点元素,它不可能是html(html文档),所以就返回true。

    这是jQuery中的方法,但是这不严谨:因为XML的根节点可能是HTML标签。(但谁这么无聊去那样创建xml呢)

    有一种更严谨的方法:

    var isXML = function(doc){

        //xml文档创建元素时,传入小写的字母,取它的nodeName时就是小写。而HTML文档,不管传入的是小写还是大写,取它的nodeName时,都会是大写

      return doc.createElement("p").nodeName !== doc.createElement("P").nodeName;

    }

    2.判定两个节点的关系

    nodeA.compareDocumentPosition(nodeB)返回的结果:           //标准浏览器支持,低版本浏览器不支持

    0:  元素一致

    1:  节点在不同的文档(或有一个节点在文档之外)

    2:  节点B在节点A之前

    4:  节点A在节点B之前

    8:  节点B包含节点A

    16:  节点A包含节点B

    32:  浏览器的私有使用

    当然,两个元素的位置关系可能满足以上两种情况,比如:A包含B,并且A在B的前面,这时就返回16+4=20.

    为了兼容低版本浏览器,可以用IE的私有属性sourceIndex处理,sourceIndex会根据元素的位置从上到下,从左到右依次加1,比如HTML标签的sourceIndex为0,HEAD标签为1,BODY标签为2,HEAD的第一个子元素为3...,如果元素不在DOM树中,就返回-1.

    3.节点排序

    为了让选择器引擎搜索到的结果集与原生API结果一样,我们需要让元素节点按它们在DOM树出现的顺序排序。

    (1)在IE以及Opera早期版本,可以使用sourceIndex进行排序。标准浏览器可以使用compareDocumentPosition判断,来排序。

    (2)标准浏览器的Range对象有一个compareBoundaryPoints方法,它能迅速的得到两个元素的前后顺序。要兼容旧版本浏览器和XML文档,可以使用nextSibling等DOM API来处理。(所谓"Range",是指HTML文档中的任意一段内容。一个Range的起始点和结束点位置可以任意,甚至起始点和结束点可以是一样的(也就是空Range)。最常见的Range是用户文本选择范围(user text selection)。当用户选择了页面上的某一段文字后,你就可以把这个选择转为Range。当然,你也可以直接用程序定义Range。)

    (3)我们用选择器引擎选择好了之后,用document.getElementsByTagName("*")得到所有元素节点,这时它们肯定是排好序的。我们依次为它们添加一个类似sourceIndex的自定义属性,值为它的索引值。然后再去匹配选择器引擎选择好的结果,就可以排序了。

    这里有一个tip跟大家说下:数组原生的sort方法,每个浏览器使用的排序算法都不一样。但是当它传入一个比较函数时,不管内部使用的是哪种排序算法,都需要多次比对,非常耗时。

    这里讲一下经常会出现的面试题:对元素节点进行排序。我们可以把元素节点附在String对象数组中,比如:[{"0":元素1},{"1":元素2},{"2":元素3}],对这个数组逆序,然后根据数组的顺序取元素,元素节点就逆序了。

    4.切割器

    切割器就是对用户的选择符进行切割,这个步骤就像编译原理的词法分析,拆分出有用的符号出来。

    比如:对于".td1,div a,body"这种选择符字符串,我们必须使用正则将它分解成以下数组:[".td1",",","div"," ","*",",","body"]。

    然后就可以根据这个数组中的每项进行元素的创建和过滤了。最终去重排序,得到用户想要的元素。

    这里主要用来正则表达式来处理字符串,需要强大的正则表达式基础,适合深入研究正则的人。

    加油!

  • 相关阅读:
    第二阶段第二次spring会议
    第一次冲刺阶段的改进方案
    第二阶段第一次spring会议
    第七次spring会议
    第六次spring会议
    第五次spring会议
    第四次spring会议
    第三次spring会议
    第二次spring会议
    第一次spring会议
  • 原文地址:https://www.cnblogs.com/chaojidan/p/4139465.html
Copyright © 2020-2023  润新知