原生的html元素选择器的实现,类似jquery选择器

做前端,需要选择元素,虽说有jquery和各大js库已经帮我造好了轮子,但我想试试自己实现一个,正好项目也不忙,正好加入自己的js文件中,下面是实现代码。用$g(“#content .op”)这种格式就可以调用,和jquery $()的参数一样: 精心开发5年的UI前端框架!

function $findChilds(parentNode, text)
{
    //如果不传入父节点的话,默认为body
    if(parentNode == undefined)
        parentNode = document.body;
    var childNodes = parentNode.childNodes;
    var results = [];
    //子节点大于零才循环
    if(childNodes.length > 0)
    {
        var length = childNodes.length;
        //循环查找符合text的节点
        for(var i=0;i<length;++i)
        {
            //三种情况,className,id, tagName
            switch(text.substr(0, 1))
            {
            case '.':
                //这两种:parentNode.getElementsByClassName,parentNode.all
//都是后来加上的,如果浏览器这两种方法都不支持,那就只能暴力递归了
                if(parentNode.getElementsByClassName)
                    return parentNode.getElementsByClassName(text.substr(1));
                else if(parentNode.all)
                {
                    var finded = [];
                    var jlength = parentNode.all.length;
                    for(var j=0;j<jlength;++j)
                        if(parentNode.all[j].className == text.substr(1))
                            finded.push(parentNode.all[j]);
                    return finded;
                }
                //以上两种方法都不支持,直接判断
                if(childNodes[i].className == text.substr(1))
                    results.push(childNodes[i]);
                break;
            case '#':
                return [document.getElementById(text.substr(1))];
            default:
                return parentNode.getElementsByTagName(text);
            }
            //判断完后,把当前子元素的子元素传入$findChilds进行递归查找,返回的结果直接和现在的结果合并
            results = results.concat($findChilds(childNodes[i], text));
        }
    }
    return results;
}   

String.prototype.vtrim = function() {
      return this.replace(/^\s+|\s+$/g, '');
}   

function $g(text)
{
    //按照空格分割参数
    var values = text.vtrim().split(" ");
    var length = values.length;
    //如果只有一个选择参数的话,就直接调用dom方法返回结果。
    if(length == 1)
        switch(values[0].substr(0, 1))
        {
        case "#":
            return document.getElementById(values[0].substr(1));
        case ".":
            if(document.getElementsByClassName)
                return document.getElementsByClassName(values[0].substr(1));
        default:
            return document.getElementsByTagName(values[0]);
        }
    //每次迭代都会产生许多符合参数的结果节点,这里结果节点的名称为parentNodes,第一次循环默认为body
    var parentNodes = [document.body];
    //外层循环为迭代每个传入的参数
    for(var i = 0; i < length; ++i)
    {
        var jlength = parentNodes.length;
        var results = [];
        //这里如果values的长度为零的话,
        //就说明是多出来的空格,
        //例如:$g("      .content");这种情况不执行代码直接跳入下一循环
        var tmpValue = values[i].vtrim();
        if(tmpValue.length <= 0)
            continue;
        //内层循环为迭代每个结果节点,
        //在结果节点中查找符合选择条件的结果。当然第一次为body
        for(var j=0;j<jlength;++j)
        {
            //$findChilds就是上边的那个函数,就是选择某个节点的子节点的
            var result = $findChilds(parentNodes[j], values[i].vtrim());
            var rlength = result.length;
            //因为返回的有时候是html容器,无法直接和数组concat所以倒入数组,这里有优化空间,但暂不考虑性能先这么做
            for (var k = 0; k < rlength; ++k)
                results.push(result[k]);
        }
        //没有结果,立即返回undefined
        if(results == undefined || results.length <= 0)
            return undefined;
        //最后一次循环就直接返回结果数组,但是如果最后一个选择条件是选择id的话,那就不返回数组直接返回dom对象了
        if (i == length - 1)
        {
            if (values[i].substr(0, 1) == "#")
                return results[0];
            return results;
        }
        parentNodes = results;
    }
}

经过在ff ie6下的测试 单纯的选择id比jquery要快很多,

其他的部分选择模式我测试的少数比jquery要快。 精心开发5年的UI前端框架!

当然测试不可能全面,还可能会有bug,而且不支持类似于.content:first-child这样的伪类选择。

时间: 2024-10-17 16:33:50

原生的html元素选择器的实现,类似jquery选择器的相关文章

实现一个类似jquery选择器的小轮子(一)

 最近在做移动端的项目,主管说不用jq,尽量用轻量级的类库.但是自己对jq的选择器又比较依靠,因此尝试着在两晚的时间里自己做一个选择器出来,功能当然也是尽量像jq靠拢. 先大致的整理下自己的思路: 每一次遍历dom元素,每一次遍历到的元素便是下一次遍历到的元素的父级. <div class="firstPapas"><!--第一个父级--> <li class="secondsPapa"><!--第二个父级--> &l

实现一个类似jquery选择器的小轮子(二)

大致的思路已经整理出来, 上一次遍历到的子级是下一次遍历到的父级; 首先开始是对$(str)里面的str字符串进行切片; var str = ' div .abc .edf ' $(str); //切片思路如下 //首先在使用选择器时可能手误,前面空了空格,或者后面空了空格:为了增加容错性,在此先对字符串使用trim方法. str = str.replace(/^\s+|\s+$/g,''); console.log(str);//得到'div .abc .edf'; //开始对字符串进行切割

jQuery内核详解与实践读书笔记2:破解jQuery选择器接口1

前两篇已经介绍了如何搭建一个jQuery框架的雏形,从这一篇开始详细了解jQuery选择器的接口.jQuery选择器功能强大但用法很简单,它仅仅提供了一个接口:jQuery(),也可以简写为$(). 1. 简单但很复杂的黑洞 jQuery提供了唯一的接口(jQuery()或$())使选择器与外界进行交流.jQuery框架的基础是查询,即查询文档元素对象,因此可以认为jQuery对象就是一个选择器,并在此基础上构建和运行查询过滤器.jQuery查询结果的数据集合是jQuery对象的一部分.在$()

jQuery选择器大全(48个代码片段+21幅图演示)

选择器是jQuery最基础的东西,本文中列举的选择器基本上囊括了所有的jQuery选择器,也许各位通过这篇文章能够加深对jQuery选择器的理解,它们本身用法就非常简单,我更希望的是它能够提升个人编写jQuery代码的效率.本文配合截图.代码和简单的概括对所有jQuery选择器进行了介绍,也列举出了一些需要注意和区分的地方. 一.基本选择器 1. id选择器(指定id元素) 将id="one"的元素背景色设置为黑色.(id选择器返单个元素) $(document).ready(func

jQuery选择器详解及实例---《转载》

选择器是jQuery最基础的东西,本文中列举的选择器基本上囊括了所有的jQuery选择器,也许各位通过这篇文章能够加深对jQuery选择器的理解,它们本身用法就非常简单,我更希望的是它能够提升个人编写jQuery代码的效率.本文配合截图.代码和简单的概括对所有jQuery选择器进行了介绍,也列举出了一些需要注意和区分的地方. 一.基本选择器 1. id选择器(指定id元素) 将id="one"的元素背景色设置为黑色.(id选择器返单个元素) $(document).ready(func

使用jquery选择器大全的用法介绍

在jquery开发(http://www.maiziedu.com/course/python/303-2785/)当中,很多人都很在意选择器的问题,首先选择器是jQuery最基础的东西,也对获得页面元素变得更加容易.更加灵活,能减轻工程师的开发压力,本文主要加深对选择器的理解以及用法,帮助提升个人编写jQuery代码的效率.下面就一起看看对所有jQuery选择器的介绍,并且也列举出了一些需要注意和区分的地方. 一.基本选择器 1. id选择器(指定id元素) 将id="one"的元素

jQuery选择器。 5.21 《深夜还在编码的你》

(之所以字体弄那么大是因为省眼,程序员不容易,程序员的眼睛更不容易,请保护我们的眼睛) 选择器是jQuery的根基,在jQuery中,对事件处理.遍历DOM和Ajax操作都依赖于选择器. 熟练地使用选择器,不但能简化代码,而且能够事半功倍. jQuery选择器可通过CSS选择器.条件过滤两种方式获取元素. 可以通过CSS选择器语法规则获取元素的jQuery选择器包括基本选择器.层次选择器和属性选择器: 可以通过条件过滤选取元素的jQuery选择器包括基本过滤选择器和可见性过滤选择器. jQuer

JQuery选择器学习系列 【赞】

从零开始学习jQuery (二) 万能的选择器 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 从零开始学习jQuery (五) 事件与事件对象 从零开始学习jQuery (六) jQuery中的Ajax 从零开始学习jQuery (七) jQuery动画-让页面动起来! 从零开始学习jQuery (八

淘宝自己的前端框架KISSY(类似jquery) - 简易指南

KISSY 是由阿里集团前端工程师们发起创建的一个开源 JS 框架. 具备模块化.高扩展性.组件齐全,接口一致.自主开发.适合多种应用场景等特性. 在以下方面具有一定优势: A.拥有大量的中文文档: B.在国内具备一定的社区规模: C.开发便捷: D.综合借鉴国际先进的框架类库设计: E.应用场景广泛. 下载引入 KISSY 1.3.0 KISSY seed 1.3.0 引入方式有两种: 1.核心全部加载引入完整的 KISSY 2.按需加载模块引入 seed 引入完整的 KISSY 引入完整的