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 相关文章推荐
JavaScript 在网页上单击鼠标的地方显示层及关闭层
Dec 30 Javascript
JavaScript获取和设置CheckBox状态的简单方法
Jul 05 Javascript
页面载入结束自动调用js函数示例
Sep 23 Javascript
js this函数调用无需再次抓获id,name或标签名
Mar 03 Javascript
node.js 开发指南 ? Node.js 连接 MySQL 并进行数据库操作
Jul 29 Javascript
javascript中加var和不加var的区别 你真的懂吗
Jan 06 Javascript
Javascript HTML5 Canvas实现的一个画板
Apr 12 Javascript
js微信分享API
Oct 11 Javascript
获取JavaScript异步函数的返回值
Dec 21 Javascript
使用JS模拟锚点跳转的实例
Feb 01 Javascript
Vue项目中如何引入icon图标
Mar 28 Javascript
angularjs $http调用接口的方式详解
Aug 13 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使用array_search函数实现数组查找的方法
2015/06/12 PHP
WordPress开发中用于获取近期文章的PHP函数使用解析
2016/01/05 PHP
PHP中Laravel 关联查询返回错误id的解决方法
2017/04/01 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
PHP使用Curl实现模拟登录及抓取数据功能示例
2018/04/27 PHP
javascript实现的图片预览功能
2017/03/25 Javascript
JavaScript数组去重算法实例小结
2018/05/07 Javascript
vue中的$emit 与$on父子组件与兄弟组件的之间通信方式
2018/05/13 Javascript
vue.js中toast用法及使用toast弹框的实例代码
2018/08/27 Javascript
vue服务端渲染页面缓存和组件缓存的实例详解
2018/09/18 Javascript
详解webpack打包后如何调试的方法步骤
2018/11/07 Javascript
Cookbook组件形式:优化 Vue 组件的运行时性能
2018/11/25 Javascript
使用 webpack 插件自动生成 vue 路由文件的方法
2019/08/20 Javascript
[03:30]DOTA2完美“圣”典精彩集锦
2016/12/27 DOTA
python 每天如何定时启动爬虫任务(实现方法分享)
2018/05/21 Python
python ftp 按目录结构上传下载的实现代码
2018/09/12 Python
[原创]Python入门教程1. 基本运算【四则运算、变量、math模块等】
2018/10/28 Python
python2.7实现邮件发送功能
2018/12/12 Python
解决PySide+Python子线程更新UI线程的问题
2019/01/11 Python
flask框架jinja2模板与模板继承实例分析
2019/08/01 Python
使用pandas 将DataFrame转化成dict
2019/12/10 Python
Django中密码的加密、验密、解密操作
2019/12/19 Python
Python3.7 读取音频根据文件名生成脚本的代码
2020/04/07 Python
tensorflow 动态获取 BatchSzie 的大小实例
2020/06/30 Python
python FTP编程基础入门
2021/02/27 Python
CSS3中设置3D变形的transform-style属性详解
2016/05/23 HTML / CSS
AP澳洲中文网:澳洲正品直邮,包税收件无忧
2019/07/12 全球购物
纬创Java面试题笔试题
2014/10/02 面试题
经典而简洁的婚礼主持词
2014/03/13 职场文书
感情真挚的毕业生求职信
2014/07/19 职场文书
招标授权委托书样本
2014/09/23 职场文书
顶岗实习计划书
2015/01/16 职场文书
大学生见习总结报告
2015/06/24 职场文书
2016党员干部反腐倡廉心得体会
2016/01/13 职场文书
MySQL 1130异常,无法远程登录解决方案详解
2021/08/23 MySQL
vue-cli3.x配置全局的scss的时候报错问题及解决
2022/04/30 Vue.js