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脚本特性
Sep 13 Javascript
页面回到顶部的三种实现(锚标记,js)
Oct 01 Javascript
正则表达式搭配js轻松处理json文本方便而老古
Feb 17 Javascript
Javascript Event(事件)的传播与冒泡
Jan 23 Javascript
vue cli 全面解析
Feb 28 Javascript
vue中的模态对话框组件实现过程
May 01 Javascript
详解JavaScript 中 if / if...else...替换方式
Jul 15 Javascript
原生js实现淘宝放大镜效果
Oct 28 Javascript
JavaScript基于数组实现的栈与队列操作示例
Dec 22 Javascript
d3.js实现图形拖拽
Dec 19 Javascript
vuex中store存储store.commit和store.dispatch的用法
Jul 24 Javascript
ant design vue 表格table 默认勾选几项的操作
Oct 31 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 strtotime函数详解
2009/12/18 PHP
PHP5.4中json_encode中文转码的变化小结
2013/01/30 PHP
php使用mkdir创建多级目录入门例子
2014/05/10 PHP
thinkphp配置连接数据库技巧
2014/12/02 PHP
使用PHP连接数据库_实现用户数据的增删改查的整体操作示例
2017/09/01 PHP
thinkphp5.1框架容器与依赖注入实例分析
2019/07/23 PHP
Laravel数据库读写分离配置的方法
2019/10/13 PHP
HR vs CL BO3 第一场 2.13
2021/03/10 DOTA
js中判断Object、Array、Function等引用类型对象是否相等
2012/08/29 Javascript
jQuery Mobile的loading对话框显示/隐藏方法分享
2013/11/26 Javascript
JS+CSS实现带有碰撞缓冲效果的竖向导航条代码
2015/09/15 Javascript
详解JavaScript基于面向对象之创建对象(1)
2015/12/10 Javascript
JQuery用户名校验的具体实现
2016/03/18 Javascript
vue使用Axios做ajax请求详解
2017/06/07 Javascript
js将键值对字符串转为json字符串的方法
2018/03/30 Javascript
Vue单页及多页应用全局配置404页面实践记录
2018/05/22 Javascript
validform表单验证的实现方法
2019/03/08 Javascript
vue设置动态请求地址的例子
2019/11/01 Javascript
让IDE识别webpack的别名alias的实现方法
2020/05/06 Javascript
Vue自定义多选组件使用详解
2020/09/08 Javascript
Python通过websocket与js客户端通信示例分析
2014/06/25 Python
用Eclipse写python程序
2018/02/10 Python
python基础教程项目三之万能的XML
2018/04/02 Python
Python namedtuple命名元组实现过程解析
2020/01/08 Python
简单了解django文件下载方式
2020/02/10 Python
GetYourGuide台湾:预订旅游活动、景点和旅游项目
2019/06/10 全球购物
The Body Shop美体小铺西班牙官网:天然化妆品
2019/06/21 全球购物
敲诈同学钱财检讨书范文
2014/11/18 职场文书
2015年学校党支部工作总结
2015/04/01 职场文书
2015年学校后勤工作总结
2015/04/08 职场文书
安全员岗位职责范本
2015/04/11 职场文书
2016年6.5世界环境日宣传活动总结
2016/04/01 职场文书
2016年学校禁毒宣传活动工作总结
2016/04/05 职场文书
导游词之千岛湖
2019/09/23 职场文书
简单聊聊TypeScript只读修饰符
2022/04/06 Javascript
解决IIS7下无法绑定https主机的问题
2022/04/29 Servers