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 相关文章推荐
判断脚本加载是否完成的方法
May 26 Javascript
js静态方法与实例方法分析
Jul 04 Javascript
超级有用的13个基于jQuery的内容滚动插件和教程
Jul 31 Javascript
自定义jQuery插件方式实现强制对象重绘的方法
Mar 23 Javascript
JavaScript调用客户端Java程序的方法
Jul 27 Javascript
原生JavaScript制作微博发布面板效果
Mar 11 Javascript
JS原生轮播图的简单实现(推荐)
Jul 22 Javascript
JavaScript引用类型Object常见用法实例分析
Aug 08 Javascript
小程序点赞收藏功能的实现代码示例
Sep 07 Javascript
vue项目中仿element-ui弹框效果的实例代码
Apr 22 Javascript
泛谈JS逻辑判断选择器 || &amp;&amp;
May 24 Javascript
Vue使用虚拟dom进行渲染view的方法
Dec 26 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全概率运算函数(优化版) Webgame开发必备
2011/07/04 PHP
php设计模式小结
2013/02/15 PHP
laravel使用数据库测试注意事项
2020/04/10 PHP
JavaScript Cookie显示用户上次访问的时间和次数
2009/12/08 Javascript
jQuery 选择器理解
2010/03/16 Javascript
公共js在页面底部加载的注意事项介绍
2013/07/18 Javascript
原生JS实现跑马灯效果
2017/02/20 Javascript
JavaScript中数组Array方法详解
2017/02/27 Javascript
js实现延迟加载的几种方法
2017/04/24 Javascript
使用Node.js实现简易MVC框架的方法
2017/08/07 Javascript
浅谈AngularJs 双向绑定原理(数据绑定机制)
2017/12/07 Javascript
webpack external模块的具体使用
2018/03/10 Javascript
vue .sync修饰符的使用详解
2018/06/15 Javascript
Jquery遍历筛选数组的几种方法和遍历解析json对象,Map()方法详解以及数组中查询某值是否存在
2019/01/18 jQuery
从0到1构建vueSSR项目之路由的构建
2019/03/07 Javascript
微信小程序实现上传图片裁剪图片过程解析
2019/08/22 Javascript
layui问题之模拟table表格中的选中按钮选中事件的方法
2019/09/20 Javascript
Node.js API详解之 module模块用法实例分析
2020/05/13 Javascript
JavaScript实现烟花绽放动画效果
2020/08/04 Javascript
如何HttpServletRequest文件对象并储存
2020/08/14 Javascript
[05:45]Ti4观战指南(下)
2014/07/07 DOTA
[00:12]2018DOTA2亚洲邀请赛 sylar表现SOLO技艺
2018/04/06 DOTA
Python中__init__和__new__的区别详解
2014/07/09 Python
TensorFlow实现简单的CNN的方法
2019/07/18 Python
Python生成验证码、计算具体日期是一年中的第几天实例代码详解
2019/10/16 Python
keras实现调用自己训练的模型,并去掉全连接层
2020/06/09 Python
Python selenium爬取微信公众号文章代码详解
2020/08/12 Python
台湾百利市购物中心:e-Payless
2017/08/16 全球购物
Python面试题:Python里面如何生成随机数
2015/03/12 面试题
个人对照检查材料
2014/02/12 职场文书
北体毕业生求职信
2014/02/28 职场文书
创先争优活动心得体会
2014/09/04 职场文书
人事局接收函
2015/01/30 职场文书
Vue鼠标滚轮滚动切换路由效果的实现方法
2021/08/04 Vue.js
Python 实现Mac 屏幕截图详解
2021/10/05 Python
Python面向对象编程之类的概念
2021/11/01 Python