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


Posted in Javascript onJune 07, 2016

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>

以上这篇jQuery原理系列-css选择器的简单实现就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery autocomplete自动完成插件的的使用方法
Aug 07 Javascript
精通Javascript系列之数据类型 字符串
Jun 08 Javascript
javascript控制在光标位置插入文字适合表情的插入
Jun 09 Javascript
理运用命名空间让js不产生冲突避免全局变量的泛滥
Jun 15 Javascript
js中字符串编码函数escape()、encodeURI()、encodeURIComponent()区别详解
Apr 01 Javascript
漂亮实用的页面loading(加载)封装代码
Feb 03 Javascript
基于angular2 的 http服务封装的实例代码
Jun 29 Javascript
vue.js如何更改默认端口号8080为指定端口的方法
Jul 14 Javascript
JS实现前端页面的搜索功能
Jun 12 Javascript
关于AngularJS中ng-repeat不更新视图的解决方法
Sep 30 Javascript
Vue项目history模式下微信分享爬坑总结
Mar 29 Javascript
为什么JavaScript中0.1 + 0.2 != 0.3
Dec 03 Javascript
javascript实现抽奖程序的简单实例
Jun 07 #Javascript
浅谈javascript中new操作符的原理
Jun 07 #Javascript
mvvm双向绑定机制的原理和实现代码(推荐)
Jun 07 #Javascript
jQuery原理系列-常用Dom操作详解
Jun 07 #Javascript
浅析BootStrap栅格系统
Jun 07 #Javascript
浅谈jQuery 选择器和dom操作
Jun 07 #Javascript
BootStrap.css 在手机端滑动时右侧出现空白的原因及解决办法
Jun 07 #Javascript
You might like
php 用checkbox一次性删除多条记录的方法
2010/02/23 PHP
ThinkPHP使用心得分享-上传类UploadFile的使用
2014/05/15 PHP
php libevent 功能与使用方法详解
2020/03/04 PHP
extjs中grid中嵌入动态combobox的应用
2011/01/01 Javascript
JS简单的图片放大缩小的两种方法
2013/11/11 Javascript
Area 区域实现post提交数据的js写法
2014/04/22 Javascript
javascript跨域原因以及解决方案分享
2015/04/08 Javascript
Bootstrap实现响应式导航栏效果
2015/12/28 Javascript
基于javascript实现样式清新图片轮播特效
2016/03/30 Javascript
仿iframe效果Aajx文件上传实例
2016/11/18 Javascript
Vue2实现组件props双向绑定
2016/12/02 Javascript
Angular ui.bootstrap.pagination分页
2017/01/20 Javascript
Bootstrap笔记—折叠实例代码
2017/03/13 Javascript
微信小程序 页面跳转传值实现代码
2017/07/27 Javascript
详解bootstrap用dropdown-menu实现上下文菜单
2017/09/22 Javascript
浅谈angular2路由预加载策略
2017/10/04 Javascript
laydate日历控件使用方法详解
2017/11/20 Javascript
Vue2.2.0+新特性整理及注意事项
2018/08/22 Javascript
vue Cli 环境删除与重装教程 - 版本文档
2020/09/11 Javascript
js实现类选择器和name属性选择器的示例步骤
2021/02/07 Javascript
Python中文编码那些事
2014/06/25 Python
使用Python的Django框架实现事务交易管理的教程
2015/04/20 Python
python逐行读写txt文件的实例讲解
2018/04/03 Python
python写入并获取剪切板内容的实例
2018/05/31 Python
Python 旋转打印各种矩形的方法
2019/07/09 Python
Python压缩模块zipfile实现原理及用法解析
2020/08/14 Python
用CSS禁用输入法(CSS3 UI规范)实例解析
2012/12/04 HTML / CSS
香蕉共和国加拿大官网:Banana Republic加拿大
2018/08/06 全球购物
简单介绍Object类的功能、常用方法
2013/10/02 面试题
学生周末长期请假条
2014/02/15 职场文书
摄影专业毕业生求职信
2014/03/13 职场文书
中秋寄语大全
2014/04/11 职场文书
《风娃娃》教学反思
2014/04/19 职场文书
四查四看自我剖析材料
2014/09/19 职场文书
网络研修随笔感言
2015/11/18 职场文书
浅谈Laravel中使用Slack进行异常通知
2021/05/29 PHP