• getElementsByClassName的实现


    首先我们看jquery作者的一篇getElementsByClassName Speed Comparison

    有三种实现

    1 纯DOM:通过getElementsByClassName("*")来遍历所有的dom元素,然后用正则判断className

    2 DOM TreeWalker:dom2实现

    3 XPath:通过XPath引擎来实现遍历

    dom TreeWalker。通过使用dom level 2实现。

    document.getElementsByClass = function(needle) {
    function acceptNode(node) {
    if (node.hasAttribute("class")) {
    var c = " " + node.className + " ";
    if (c.indexOf(" " + needle + " ") != -1)
    return NodeFilter.FILTER_ACCEPT;
    }
    return NodeFilter.FILTER_SKIP;
    }
    var treeWalker = document.createTreeWalker(document.documentElement,
    NodeFilter.SHOW_ELEMENT, acceptNode,
    true);
    var outArray = new Array();
    if (treeWalker) {
    var node = treeWalker.nextNode();
    while (node) {
    outArray.push(node);
    node
    = treeWalker.nextNode();
    }
    }
    return outArray;
    }

    ulitimate  getElementsByClassName

    使用纯dom实现,对ie实现了一些优化

    function getElementsByClassName(oElm, strTagName, strClassName){
    var arrElements = (strTagName == "*" && oElm.all)? oElm.all :
    oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    strClassName
    = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
    oElement
    = arrElements[i];
    if(oRegExp.test(oElement.className)){
    arrReturnElements.push(oElement);
    }
    }
    return (arrReturnElements)
    }

    Dustin Diaz's getElementsByClass
    一个纯dom实现

    function getElementsByClass(searchClass,node,tag) {
    var classElements = new Array();
    if ( node == null )
    node
    = document;
    if ( tag == null )
    tag
    = '*';
    var els = node.getElementsByTagName(tag);
    var elsLen = els.length;
    var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
    for (i = 0, j = 0; i < elsLen; i++) {
    if ( pattern.test(els[i].className) ) {
    classElements[j]
    = els[i];
    j
    ++;
    }
    }
    return classElements;
    }

    prototype1.5的XPath

    document.getElementsByClassName = function(className, parentElement) {
    if (Prototype.BrowserFeatures.XPath) {
    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
    return document._getElementsByXPath(q, parentElement);
    }
    else {
    var children = ($(parentElement) || document.body).getElementsByTagName('*');
    var elements = [], child;
    for (var i = 0, length = children.length; i < length; i++) {
    child
    = children[i];
    if (Element.hasClassName(child, className))
    elements.push(Element.extend(child));
    }
    return elements;
    }
    };

    Native firfefox3用C++写的

    document.getElementsByClassName

    速度对照表

    getElementsByClassName对比

    下面我们写一个getElementsByClassName的实现

    var getElementsByClassName = function (searchClass, node,tag) {
        var classes = searchClass.split(" "),returnElements = [];
        if(document.getElementsByClassName){
    	for(var mm1=0;mm1<classes.length;mm1++)	
    	for(var mm2=0;mm2<document.getElementsByClassName(classes[mm1]).length;mm2++)
          returnElements.push(document.getElementsByClassName(classes[mm1])[mm2]);
        }else{
            node = node || document;
            tag = tag || "*";
          var elements = (tag === "*" && node.all)? node.all : node.getElementsByTagName(tag),
            patterns = [],
            current,
            match;
            var i = classes.length;
            while(--i >= 0){
                patterns.push(new RegExp("(^|\\s)" + classes[i] + "(\\s|$)","i"));
            }
            var j = elements.length;
            while(--j >= 0){
                current = elements[j];
                match = false;
                for(var k=0, kl=patterns.length; k<kl; k++){
                    match = patterns[k].test(current.className);
                }
              if (match)  returnElements.push(current);
            }
        }
    	        return returnElements;
    }
    

    用法:getElementsByClassName("class1 class2")
    参数:可接受多个class参数

    返回:返回所有包含class1或者class2的元素

  • 相关阅读:
    深入分析 Java 中的中文编码问题
    随便写写20160411
    Linux GDB 程序调试工具使用详解
    「美国花好几亿造出太空圆珠笔后,发现苏联航天员用铅笔」的故事真实吗?
    verynginx部署
    harbor私有仓库部署
    rancher学习
    harbor部署
    zabbix-proxy docker
    NFS部署
  • 原文地址:https://www.cnblogs.com/lunalord/p/1987268.html
Copyright © 2020-2023  润新知