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.boxy插件的iframe扩展代码
Jul 02 Javascript
jquery插件之easing 动态菜单
Aug 21 Javascript
基于mootools插件实现遮罩层新手引导
May 24 Javascript
简单js代码实现selece二级联动(推荐)
Feb 18 Javascript
Juery解决tablesorter中文排序和字符范围的方法
May 06 Javascript
简介JavaScript中的italics()方法的使用
Jun 08 Javascript
jQuery实现加入收藏夹功能(主流浏览器兼职)
Dec 24 Javascript
Bootstrap模态框(Modal)实现过渡效果
Mar 17 Javascript
BootStrap Table前台和后台分页对JSON格式的要求
Jun 28 Javascript
JavaScript&quot;模拟事件&quot;的注意要点详解
Feb 13 Javascript
JS实现transform实现扇子效果
Jan 17 Javascript
浅谈vue使用axios的回调函数中this不指向vue实例,为undefined
Sep 21 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跨时区(UTC时间)应用解决方案
2013/01/11 PHP
php读取大文件示例分享(文件操作类)
2014/04/13 PHP
PHP观察者模式原理与简单实现方法示例
2017/08/25 PHP
Yii框架视图、视图布局、视图数据块操作示例
2019/10/14 PHP
使用Jquery搭建最佳用户体验的登录页面之记住密码自动登录功能(含后台代码)
2011/07/10 Javascript
SyntaxHighlighter语法高亮插件使用说明
2011/08/14 Javascript
JavaScript组合拼接字符串的效率对比测试
2014/11/06 Javascript
js实现选中复选框文字变色的方法
2015/08/14 Javascript
DEDECMS如何为文章添加HOT NEW标志图片
2015/08/14 Javascript
Vue数据驱动模拟实现3
2017/01/11 Javascript
Ajax验证用户名或昵称是否已被注册
2017/04/05 Javascript
react+ant design实现Table的增、删、改的示例代码
2018/12/27 Javascript
微信小程序时间选择插件使用详解
2018/12/28 Javascript
vue项目前端错误收集之sentry教程详解
2019/05/27 Javascript
layui自定义插件citySelect实现省市区三级联动选择
2019/07/26 Javascript
vue自动化路由的实现代码
2019/09/30 Javascript
JavaScript逻辑运算符相关总结
2020/09/04 Javascript
[58:32]EG vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python删除列表中重复记录的方法
2015/04/28 Python
Python中的数学运算操作符使用进阶
2016/06/20 Python
python定间隔取点(np.linspace)的实现
2019/11/27 Python
如何定义TensorFlow输入节点
2020/01/23 Python
Python之变量类型和if判断方式
2020/05/05 Python
Python代码中如何读取键盘录入的值
2020/05/27 Python
QT5 Designer 打不开的问题及解决方法
2020/08/20 Python
Python爬取网页信息的示例
2020/09/24 Python
个人素质的自我评价分享
2013/12/16 职场文书
怎样写演讲稿
2014/01/04 职场文书
开学寄语大全
2014/04/08 职场文书
中学生家长评语大全
2014/04/16 职场文书
优秀家长事迹材料
2014/05/17 职场文书
感恩教育观后感
2015/06/17 职场文书
改进工作作风心得体会
2016/01/23 职场文书
Python实现学生管理系统(面向对象版)
2021/06/24 Python
如何利用 CSS Overview 面板重构优化你的网站
2021/10/24 HTML / CSS
MySQL高级进阶sql语句总结大全
2022/03/16 MySQL