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之大字符串的连接的StringBuffer 类
May 08 Javascript
更正确的asp冒泡排序
May 24 Javascript
javascript 计算两个整数的百分比值
Dec 26 Javascript
JS的事件绑定深入认识
Jun 26 Javascript
JavaScript对象参数的引用传递
Jan 14 Javascript
AngularJS基础 ng-href 指令用法
Aug 01 Javascript
JS实现选定指定HTML元素对象中指定文本内容功能示例
Feb 13 Javascript
angularjs之$timeout指令详解
Jun 13 Javascript
JS实现的文字间歇循环滚动效果完整示例
Feb 13 Javascript
JavaScript原型对象、构造函数和实例对象功能与用法详解
Aug 04 Javascript
JavaScript创建、读取和删除cookie
Sep 03 Javascript
vue实现配置全局访问路径头(axios)
Nov 01 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
smarty 原来也不过如此~~呵呵
2006/11/25 PHP
通俗易懂的php防注入代码
2010/04/07 PHP
php一行代码获取文件后缀名实例分析
2014/11/12 PHP
Yii框架在页面输出执行sql语句以方便调试的实现方法
2014/12/24 PHP
为PHP5.4开启Zend OPCode缓存
2014/12/26 PHP
tp5(thinkPHP5)框架连接数据库的方法示例
2018/12/24 PHP
Thinkphp5.0框架视图view的模板布局用法分析
2019/10/12 PHP
JS组件Bootstrap Table布局详解
2016/05/27 Javascript
JavaScript实现的CRC32函数示例
2016/11/23 Javascript
ionic中列表项增加和删除的实现方法
2017/01/22 Javascript
JavaScript中使用参数个数实现重载功能
2017/09/01 Javascript
jQuery+ajax实现动态添加表格tr td功能示例
2018/04/23 jQuery
微信小程序实现弹出层效果
2020/05/26 Javascript
Vue+Element UI+Lumen实现通用表格分页功能
2019/02/02 Javascript
原生JS实现图片懒加载之页面性能优化
2019/04/26 Javascript
vue-cli脚手架打包静态资源请求出错的原因与解决
2019/06/06 Javascript
[01:22]DOTA2神秘商店携大量周边降临完美大师赛
2017/11/07 DOTA
[55:32]2018DOTA2亚洲邀请赛 4.4 淘汰赛 EG vs LGD 第二场
2018/04/05 DOTA
linux下安装easy_install的方法
2013/02/10 Python
在Django框架中设置语言偏好的教程
2015/07/27 Python
解析Python中while true的使用
2015/10/13 Python
python学习之matplotlib绘制散点图实例
2017/12/09 Python
浅谈pycharm出现卡顿的解决方法
2018/12/03 Python
Python算法的时间复杂度和空间复杂度(实例解析)
2019/11/19 Python
python 实现目录复制的三种小结
2019/12/04 Python
经典c++面试题六
2012/01/18 面试题
护理自荐信
2013/10/22 职场文书
英语专业毕业生自荐信范文
2013/12/31 职场文书
初中数学教学反思
2014/01/16 职场文书
村干部承诺书
2014/03/28 职场文书
垃圾桶标语
2014/06/24 职场文书
德能勤绩工作总结
2015/08/11 职场文书
PyTorch 如何自动计算梯度
2021/05/23 Python
Python预测分词的实现
2021/06/18 Python
Python使用OpenCV实现虚拟缩放效果
2022/02/28 Python
JavaScript正则表达式实现注册信息校验功能
2022/05/30 Java/Android