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 相关文章推荐
JS backgroundImage控制
May 19 Javascript
Javascript Ajax异步读取RSS文档具体实现
Dec 12 Javascript
jquery不常用方法汇总
Jul 26 Javascript
TypeScript Type Innference(类型判断)
Mar 10 Javascript
全屏js头像上传插件源码高清版
Mar 29 Javascript
angularjs封装bootstrap时间插件datetimepicker
Jun 20 Javascript
JS实现的幻灯片切换显示效果
Sep 07 Javascript
谈谈target=_new和_blank的不同之处
Oct 25 Javascript
javascript笔记之匿名函数和闭包
Feb 06 Javascript
vue history 模式打包部署在域名的二级目录的配置指南
Jul 02 Javascript
ES6学习笔记之字符串、数组、对象、函数新增知识点实例分析
Jan 22 Javascript
javascript-hashchange事件和历史状态管理实例分析
Apr 18 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防范SQL注入的具体方法详解(测试通过)
2014/05/09 PHP
PHP仿微信多图片预览上传实例代码
2016/09/13 PHP
thinkphp5.1框架模板布局与模板继承用法分析
2019/07/19 PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
2019/11/25 PHP
Cookie 注入是怎样产生的
2009/04/08 Javascript
jquery教程ajax请求json数据示例
2014/01/13 Javascript
javascript作用域和闭包使用详解
2014/04/25 Javascript
Jquery图片延迟加载插件jquery.lazyload.js的使用方法
2014/05/21 Javascript
JavaScript获得页面base标签中url的方法
2015/04/03 Javascript
Webpack 实现 Node.js 代码热替换
2015/10/22 Javascript
JavaScript中数组添加值和访问值常见问题
2016/02/06 Javascript
JavaScript对象数组如何按指定属性和排序方向进行排序
2016/06/15 Javascript
JS简单实现移动端日历功能示例
2016/12/28 Javascript
jQuery实现贪吃蛇小游戏(附源码下载)
2017/03/04 Javascript
使用openSpeDiv方法实现Ecshop登录弹窗框效果
2017/03/13 Javascript
mac中利用NVM管理不同node版本的方法详解
2017/11/08 Javascript
swiper 解决动态加载数据滑动失效的问题
2018/02/26 Javascript
Vue项目webpack打包部署到Tomcat刷新报404错误问题的解决方案
2018/05/15 Javascript
vue写h5页面的方法总结
2019/02/12 Javascript
vue swipeCell滑动单元格(仿微信)的实现示例
2020/09/14 Javascript
python基础教程之popen函数操作其它程序的输入和输出示例
2014/02/10 Python
tensorflow建立一个简单的神经网络的方法
2018/02/10 Python
python提取图像的名字*.jpg到txt文本的方法
2018/05/10 Python
windows下添加Python环境变量的方法汇总
2018/05/14 Python
python中验证码连通域分割的方法详解
2018/06/04 Python
Python实现数据可视化看如何监控你的爬虫状态【推荐】
2018/08/10 Python
python ipset管理 增删白名单的方法
2019/01/14 Python
Django rstful登陆认证并检查session是否过期代码实例
2019/08/13 Python
Python之数据序列化(json、pickle、shelve)详解
2019/08/30 Python
英国著名的茶叶品牌:Whittard of Chelsea
2016/09/22 全球购物
Vero Moda西班牙官方购物网站:丹麦BESTSELLER旗下知名女装品牌
2018/04/27 全球购物
高级文秘工作总结的自我评价
2013/09/28 职场文书
舞蹈毕业生的自我评价
2014/03/05 职场文书
2015年度学校卫生工作总结
2015/05/12 职场文书
南京南京观后感
2015/06/02 职场文书
nginx location 带斜杠【 / 】与不带的区别
2022/04/13 Servers