自己实现的简单的html元素选择器,类似jquery选择器,比jquery选择器还要快!

最近做前端,需要选择元素,虽说有jquery和各大js库已经帮我造好了轮子,但我想试试自己实现一个,正好项目也不忙,正好加入自己的js文件中,下面是实现代码。用$g(“#content .op”)这种格式就可以调用,和jquery $()的参数一样:
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要快。
当然测试不可能全面,还可能会有bug,而且不支持类似于.content:first-child这样的伪类选择。

像写css选择器一样写jQuery选择器(三)【jQuery入门六】

接《像写css选择器一样写jQuery选择器(二)

五、Jquery的子元素选择器

  1. :first-child :匹配每个父元素的第一个子元素,相当于E:nth-child(0),例如:$(“ul li:first-child”);
  2. :last-child :匹配每个父元素的最后一个子元素,例如:$(“ul li: last -child”);
  3. :nth-child(index/even/odd/equation):匹配每一个父元素的第N个子或奇偶元素,例如:$(“ul li:nth-child(2)”);
  4. :only-child :如果某个元素是父元素中唯一的子元素,那将会被匹配$(“ul li:only-child”);

六、子元素选择器和过滤性选择器的一些区别

:first-child和:first:

:first只匹配一个元素,而:first-child将为每个父元素匹配一个子元素,所以:first-child匹配出来的是一个集合当然也有可能只匹配一个元素,而:first永远只能匹配到一个元素。

:last-child和:last的区别道理也是一样的; 继续阅读

像写css选择器一样写jQuery选择器(二)【jQuery入门五】

接《像写css选择器一样写jQuery选择器(一)

四:简单的过滤选择器

  1. :animated:匹配所有正在执行动画效果的元素集合;
  2. :eq(index):匹配索引为 index 的一个元素,例如:$(“div:eq(0)”)//第一个div;
  3. :even:匹配索引为偶数(双数)的元素集合,例如:$(“div:even”);
  4. :odd:匹配索引为奇数(单数)的元素集合,例如:$(“div:odd”);
  5. :first:匹配找到的第一个元素,等价于:eq(0),例如:$(“div:first”);
  6. :gt(index) :匹配索引大于 index 的 元素集合,例如:$(“div:gt(0)”)//除了第一个div外的所以div;
  7. :lt(index):匹配索引小于于 index 的 元素集合,例如:$(“div:lt(0)”);
  8. :header:匹配h1-h6的所有 元素集合;
  9. :last:匹配找到的最后一个元素,例如:$(“div:last”)//最后一个div;
  10. :not(selector):去除所有与给定选择器匹配的元素,例如:$(“input:not(:checked)”)//除了被选中的所有input;

示例代码:

< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">



jQuery简单的选择器


jQuery简单的选择器

javascript森林群规有120个会员,其中管理员120个;
javascript森林群博客目前有30作者,10篇文章;

我是愚人码头

你叫什么名字呢?
我爱javascript森林;
以为森林里有我好好多的朋友;
欢迎你加入我们;







像写css选择器一样写jQuery选择器(一)【jQuery入门四】

jQuery选择器有很大一部分的写法和css选择器的写法非常相识,

我们先来看看css选择器的写法;这些对于你应该不是很陌生,呵呵。那么我们开始学习jQuery选择器。

一、简单的jQuery选择器

首先看看最简单的jQuery选择器,再次说明jQuery选择器获取的DOM元素返回的是一个数组,及时他只返回一个元素:

查看上一篇jQuery选择器入门【jQuery入门三】中的$(”div”):标签名,$(”#nickName”):ID属性,$(”.user”):样式名及例子,

  1. $(”div”):标签名,取得DOM文档中所有div标签的元素,返回的是一个元素集合,$(”.user”):样式名:
  2. $(”#nickName”):ID属性,取得DOM文档中ID为nickName的一个元素(ps:一个文档中ID是唯一的),返回的是一个元素;
  3. $(”.user”):样式名,取得DOM文档中class为user的所有元素,返回的是一个元素集合;

这里再补充1个通配符,即*:

$(“*”):通配符,取得DOM文档中所有节点元素;例如:$(“*”).css(“color”,”#FF3300″);则整个文档的文字颜色都会显示红色。至于.css(“color”,”#FF3300″)给元素加上color:#FF3300的css样式,我们会在后面再给大家详细解释。

大家可以看看这个我们写的css选择器非常的相似,下面的例子也是一样,这样我们就非常容易理解jQuery选择器的含义了

二、jQuery的组合选择器: 继续阅读