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 相关文章推荐
常用参考资料(手册)下载或者链接
Jul 22 Javascript
用javascript自动显示最后更新时间
Mar 15 Javascript
jscript之Open an Excel Spreadsheet
Jun 13 Javascript
Ajax执行顺序流程及回调问题分析
Dec 10 Javascript
jQuery实现鼠标经过购物车出现下拉框代码(推荐)
Jul 21 Javascript
jQuery中DOM节点删除之empty与remove
Jan 20 Javascript
解决vue-cli中stylus无法使用的问题方法
Jun 19 Javascript
JS自定义函数实现时间戳转换成date的方法示例
Aug 27 Javascript
vue 微信授权登录解决方案
Apr 10 Javascript
前端 javascript 实现文件下载的示例
Nov 24 Javascript
原生JavaScript实现换肤
Feb 19 Javascript
如何利用JavaScript实现二叉搜索树
Apr 02 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
第五节--克隆
2006/11/16 PHP
使用NetBeans + Xdebug调试PHP程序的方法
2011/04/12 PHP
php file_get_contents抓取Gzip网页乱码的三种解决方法
2013/11/12 PHP
yii框架builder、update、delete使用方法
2014/04/30 PHP
详解PHP中的null合并运算符
2015/12/30 PHP
php 数组元素快速去重
2017/05/05 PHP
PHP框架laravel的.env文件配置教程
2017/06/07 PHP
laradock环境docker-compose操作详解
2019/07/29 PHP
解决FireFox下[使用event很麻烦]的问题
2006/11/26 Javascript
JS setCapture 区域外事件捕捉
2010/03/18 Javascript
jquery如何改变html标签的样式(两种实现方法)
2013/01/16 Javascript
js和jquery使按钮失效为不可用状态的方法
2014/01/26 Javascript
简单谈谈javascript代码复用模式
2015/01/28 Javascript
js使用post 方式打开新窗口
2015/02/26 Javascript
快速学习AngularJs HTTP响应拦截器
2015/12/31 Javascript
理解javascript中Map代替循环
2016/02/26 Javascript
javascript正则表达式中分组详解
2016/07/17 Javascript
JS实现表单验证功能(验证手机号是否存在,验证码倒计时)
2016/10/11 Javascript
JS遍历DOM文档树的方法实例详解
2018/04/03 Javascript
VUE简单的定时器实时刷新的实现方法
2019/01/20 Javascript
微信小程序自定义组件components(代码详解)
2019/10/21 Javascript
jQuery开发仿QQ版音乐播放器
2020/07/10 jQuery
简单文件操作python 修改文件指定行的方法
2013/05/15 Python
Python中的引用和拷贝浅析
2014/11/22 Python
Python实现二维有序数组查找的方法
2016/04/27 Python
wxPython:python首选的GUI库实例分享
2019/10/05 Python
Django异步任务线程池实现原理
2019/12/17 Python
基于CSS3实现的黑色个性导航菜单效果
2015/09/14 HTML / CSS
阿根廷票务网站:StubHub阿根廷
2018/04/13 全球购物
荷兰音乐会和音乐剧门票订购网站:Topticketshop
2019/08/27 全球购物
意大利值得信赖的在线超级药房:PillolaStore
2020/02/05 全球购物
儿科护士自我鉴定
2013/10/14 职场文书
大学三年的自我评价
2013/12/25 职场文书
高二物理教学反思
2014/02/08 职场文书
物业公司管理制度
2015/08/05 职场文书
方法汇总:Python 安装第三方库常用
2022/04/26 Python