jQuery原理系列-css选择器实现

jQuery最强大的功能在于它可以通过css选择器查找元素,它的源码中有一半是sizzle css选择器引擎的代码,在html5规范出来之后,增加了document.querySelector和document.querySelectorAll直接查找元素,如果是做移动端开发的,使用jQuery的必要性大大降低。

用js代码实现css选择器,必然是用正则表达式来识别字符串了,当然浏览器提供的原生api 效率更高,以下代码只做原理性展示,并未优先性能,

例如

1)查找id显然是用document.getElementById更高效,浏览器已经做了hash,一次性找到元素不用遍历每个节点。

2)查找 name用document.getElementsByName更高效,浏览器已经做了一个含有该name的集合,

3)查找标签名 用document.getElementsByTagName更高效,浏览器已经做了一个含有该tag集合,从这个集合中再查找子集显然可以少遍历很多的元素,至于浏览器是不是在元素创建的时候就更新了缓存的集合就不得而知了,但是从这个集合中判断是不是目标元素的子节点还要用contains也会有性能损耗。

好了,我们先不考虑用原生api优化选择器的问题,只用纯正则表达式来做一个简单的实现,先用正则判断如果含有#就是id选择器,如果含有点号就是class选择器,如果含有[]就是属性选择器,设定好查找目标后开始遍历子节点,要用递归函数遍历childNodes子节点的id,name,className,getAttribute是否匹配,如果匹配就返回该元素。完整的代码如下:

html:

<body>
    <div>

        <span id="sp_id">hello,id</span>
        <span class="sp_class">hello,class</span>
         <span name="sp_name" >hello,name</span>
         <b>hello,tag</b>
    </div>
 </body>

javascript:

<script type="text/javascript">

     function find(el, selector) { //查找子节点,用法类似jquery的find函数,仅支持id,class,attr选择器,仅支持返回匹配的第一个元素
        var m = selector.match(/([#\.\[])([\w\W]+)/i);
        var type, key,attrName, result;
        if (m) {
            if (m[1] == ".") {
                type = "class"; key = m[2];
            } else if (m[1] == "#") {
                type = "id"; key = m[2];
            } if (m[1] == "[") {
                type = "attr";
                m = m[2].match(/(\w+)=(\w+)/i);
                attrName = m[1];
                key = m[2];
            }
        } else {
            type = "tag"; key = selector;
        }

        function findChild(node) {
            var c;
            for (var i = 0; i < node.childNodes.length; i++) {
                c = node.childNodes[i];
                if (type == "class" && c.className == key) {
                    result = c;
                    return;
                } else if (type == "id" && c.id == key) {
                    result = c;
                    return;
                } else if (type == "attr" &&  c.getAttribute && c.getAttribute(attrName) == key) {
                    result = c;
                    return;
                } else if (type == "tag" && c.tagName && c.tagName.toLowerCase() == key) {
                    result = c;
                    return;
                }
                findChild(c);
            }
        }
        findChild(el);
        return result;

    }

    console.log(find(document.body,"#sp_id").innerHTML);
    console.log(find(document.body,".sp_class").innerHTML);
    console.log(find(document.body,"[name=sp_name]").innerHTML);
    console.log(find(document.body,"b").innerHTML);

    </script>
时间: 2024-08-06 20:03:37

jQuery原理系列-css选择器实现的相关文章

jQuery原理系列-常用Dom操作

1. 事件绑定$(el).bind ie使用attachEvent,其它浏览器使用addEventListener,不同的是ie多了个on前缀,this绑定在window上,需要用call和apply修正this 的指向. if (element.addEventListener) { element.addEventListener(type, handler, useCapture); } else { if (element.attachEvent) { element.attachEve

锋利的Jquery解惑系列(三)------ 各路选择器大聚会

申明:初次学习Jquery的选择器时只记得几个和css选择器类似的几个,在这里列出书上写上的各路选择器方便以后的查询和现在的学习 所有例子都来自书上 测试画面: 一.基本选择器 #id, $("#test")选取id为test的元素(惟一) .class $(".test")选取所有class为test的元素 element $("p")选取所有的<P>元素 * $("*")选取所有的元素 selector1,se

详解CSS选择器、优先级与匹配原理

最常用的五类CSS选择器 准确而简洁的运用CSS选择器会达到非常好的效果.我们不必通篇给每一个元素定义类(class)或ID,通过合适的组织,可以用最简单的方法实现同样的效果.在实际工作中,最常用的选择器有以下五类: 一.标签选择器: 顾名思议,标签选择器是直接将HTML标签作为CSS选择器,可以是p.h1.dl.strong等HTML标签.如: p{font:12px;} em{color:blue;} dl{float:left;margin-top:10px;} 二.id选择器: 我们通常

jQuery css()选择器使用说明

css选择器只是jquery中的一个功能罢了,下面我来给各位朋友详细介绍jQuery css()选择器使用方法与说明详解,有需要了解学习的同学可参考. CSS操作有一个重要的方法:CSS() CSS()有三个不同的语法,来完成各自的工作: ■$(selector).css(name,value)■$(selector).css({properties})■$(selector).css(name) 返回CSS属性使用CSS(name)返回指定的第一个匹配元素的CSS属性值: 示例 $(this)

CSS选择器和jQuery选择器的区别与联系

我们知道,jQuery选择器和CSS选择器的写法十分类似,都具有隐式迭代的特点,无需循环遍历符合选择器要求的每个元素,使用起来相对方便,通常,把css选择器用$("")包起来就成了一个jQuery选择器,如   CSS选择器 jQuery选择器 ID选择器 #myID $("myID") 类选择器 .myClass $(".myClass") 标签选择器 p $("p") 层次选择器 div > strong $(&qu

CSS选择器、优先级与匹配原理(转)

CSS选择器.优先级与匹配原理 导航

CSS选择器、优先级与匹配原理

polaris不是前台开发人员,然而作为一个Web开发者,掌握必要的前台技术也是很重要的.说实话,polaris对前台技术还是蛮感兴趣的,只是一直没有用心系统的学过,所以了解的知识有点杂.这篇文章是polaris通过网上的一些知识结合自己的问题做的一些总结,一来当作笔记,二来希望能够对初学者有点帮助. 今天在修改博客时,遇到了一个问题:给一个p标签增加一个类(class),可是执行后该class中的有些属性并没有起作用.通过Firebug查看,发现没有起作用的属性被覆盖了(呵呵,废话,要不然不会

jQuery和CSS选择器全汇总,常备复习

jQuery 选择器 实例 选取 * $("*") 所有元素 #id $("#lastname") id="lastname" 的元素 .class $(".intro") 所有 class="intro" 的元素 element $("p") 所有 <p> 元素 .class.class $(".intro.demo") 所有 class="i

css选择器jquery选择器异同

css选择器用$("")包起来就成了jQuery选择器   CSS选择器 jQuery选择器 ID选择器 #myID $('#myID') 类选择器 .myclass $('.myclass') 标签选择器 p $('p') 层次选择器 div > strong $('div>strong') css称为伪类选择器jQuery称之为过滤选择器 p:nth-child(1) $('p:nth-child(1)') CSS选择器的效率(从上至下): id选择器(#myid)类选