博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
都别说工资低了,我们来一起写简单的dom选择器吧!
阅读量:6628 次
发布时间:2019-06-25

本文共 5856 字,大约阅读时间需要 19 分钟。

前言
我师父(http://www.cnblogs.com/aaronjs/)说应当阅读框架(jquery),所以老夫就准备开始看了
然后公司的师兄原来写了个dom选择器,感觉不错啊!!!原来自己从来没有想过能写这些,所以我们今天一起来试试吧
我写的这个很简单,就是最简单的那种了,但是公司师兄写的很好。。。。。。
简单dom选择器
先上个完整的代码吧,因为我已经写起了:
 View Code
复制代码
 1 <div id="parent">
 2     <div class="child1" id="c">
 3         <div>
 4         </div>
 5         <input type="button" value="测试"  class="child1.1" />
 6     </div>
 7     <div class="child1">
 8     </div>
 9     <div class="child2">
10     </div>
11     <div class="child2 child1">
12         <div class="child1.1">
13             <input class="l" value="三层测试" />
14         </div>
15     </div>
16     <input type="button" value="测试2" />
17 </div>
复制代码
简单的结果,然后我们来简单看看我丑陋的代码:
复制代码
  1 (function () {
  2     var queryFunc = {
  3         '#': function (id) {
  4             var arr = [];
  5             arr.push(document.getElementById(id))
  6             return arr;
  7         },
  8         '.': function (className) {
  9             var els = document.getElementsByTagName('*');
 10             var reg = new RegExp('(^|\\s)' + className + '(\\s|$)');
 11             var arr = [];
 12             for (var i = 0, len = els.length; i < len; i++) {
 13                 if (reg.test(els[i].className)) {
 14                     arr.push(els[i]);
 15                 }
 16             }
 17             return arr;
 18         },
 19         'tag': function (tag) {
 20             return document.getElementsByTagName(tag);
 21         }
 22     };
 23 
 24     var filterFunc = {
 25         '#': function (el, id) {
 26             return this.commomFunc(el, function (p) {
 27                 if (p.id == id) {
 28                     return true;
 29                 }
 30             });
 31         },
 32         '.': function (el, className) {
 33             var reg = new RegExp('(^|\\s)' + className + '(\\s|$)');
 34             return this.commomFunc(el, function (p) {
 35                 if (reg.test(p.className)) {
 36                     return true;
 37                 }
 38             });
 39         },
 40         'tag': function (el, tag) {
 41             return this.commomFunc(el, function (p) {
 42                 if (p.tagName.toLowerCase() == tag) {
 43                     return true;
 44                 }
 45             });
 46         },
 47         commomFunc: function (el, callback) {
 48             var p = el;
 49             var end = false;
 50             while (!end) {
 51                 p = p.parentNode || p.parentElement || null;
 52                 if (!p) return false;
 53                 var b = callback && callback(p);
 54                 if (b) return b;
 55                 if (p.tagName == 'BODY') {
 56                     end = true;
 57                 }
 58             }
 59             return false;
 60         }
 61     };
 62 
 63     var getKV = function (str) {
 64         if (!str || typeof str != 'string') return null;
 65         var k = str.substring(0, 1);
 66         var v = str;
 67         if (k == '.' || k == '#') {
 68             v = str.substring(1, str.length);
 69         } else {
 70             k = 'tag';
 71         }
 72         return {
 73             k: k,
 74             v: v
 75         };
 76     }
 77 
 78     var query = function (str) {
 79         var kv = getKV(str)
 80         return (queryFunc[kv.k] && queryFunc[kv.k](kv.v));
 81     };
 82     var filter = function (el, str) {
 83         var kv = getKV(str);
 84         return (filterFunc[kv.k] && filterFunc[kv.k](el, kv.v));
 85     };
 86     var explodeSelector = function (str) {
 87         if (!str) return [];
 88         //第一步去掉多余的空格
 89         str = str.replace(/\s+/g, ' ');
 90         var arr = str.split(' ');
 91         return arr;
 92     };
 93     //筛选元素是否具有该属性
 94 
 95     var queryAll = function (str) {
 96         var arrSelector = explodeSelector(str);
 97         var len = arrSelector.length;
 98 
 99         //当前索引
100         var index = len - 2;
101         var curDom = null;
102         var curSelector = null;
103 
104         //第一轮筛选出来的元素
105         var els = query(arrSelector[len - 1]);
106         //只有一个选择器便直接返回了
107         if (len == 1) return els;
108 
109         while (index != -1) {
110             //获取当前的筛选选择器
111             curSelector = arrSelector[index];
112             var tmpArr = [];
113             for (var i = 0, len = els.length; i < len; i++) {
114                 var tmpEl = els[i];
115                 if (filter(tmpEl, curSelector))
116                     tmpArr.push(tmpEl);
117             }
118             els = tmpArr;
119             index--;
120         }
121         return els;
122     };
123     window.queryAll = queryAll;
124 })();
复制代码
基本思路
① 获取选择器字符串,并将之分解为一个数组
复制代码
var explodeSelector = function (str) {
    if (!str) return [];
    //第一步去掉多余的空格
    str = str.replace(/\s+/g, ' ');
    var arr = str.split(' ');
    return arr;
};
复制代码
② 与CSS选择器一致,根据各种条件选取相关元素
复制代码
 1 var queryFunc = {
 2     '#': function (id) {
 3         var arr = [];
 4         arr.push(document.getElementById(id))
 5         return arr;
 6     },
 7     '.': function (className) {
 8         var els = document.getElementsByTagName('*');
 9         var reg = new RegExp('(^|\\s)' + className + '(\\s|$)');
10         var arr = [];
11         for (var i = 0, len = els.length; i < len; i++) {
12             if (reg.test(els[i].className)) {
13                 arr.push(els[i]);
14             }
15         }
16         return arr;
17     },
18     'tag': function (tag) {
19         return document.getElementsByTagName(tag);
20     }
21 };
复制代码
③ 根据选择器与获得的dom数组,判断其父元素是否具有相关属性(id,className,tag),有便留下来,没有就不管他
过滤下来的就是我们要的元素:
复制代码
 1 var filterFunc = {
 2     '#': function (el, id) {
 3         return this.commomFunc(el, function (p) {
 4             if (p.id == id) {
 5                 return true;
 6             }
 7         });
 8     },
 9     '.': function (el, className) {
10         var reg = new RegExp('(^|\\s)' + className + '(\\s|$)');
11         return this.commomFunc(el, function (p) {
12             if (reg.test(p.className)) {
13                 return true;
14             }
15         });
16     },
17     'tag': function (el, tag) {
18         return this.commomFunc(el, function (p) {
19             if (p.tagName.toLowerCase() == tag) {
20                 return true;
21             }
22         });
23     },
24     commomFunc: function (el, callback) {
25         var p = el;
26         var end = false;
27         while (!end) {
28             p = p.parentNode || p.parentElement || null;
29             if (!p) return false;
30             var b = callback && callback(p);
31             if (b) return b;
32             if (p.tagName == 'BODY') {
33                 end = true;
34             }
35         }
36         return false;
37     }
38 };
复制代码
复制代码
 1 var queryAll = function (str) {
 2     var arrSelector = explodeSelector(str);
 3     var len = arrSelector.length;
 4 
 5     //当前索引
 6     var index = len - 2;
 7     var curDom = null;
 8     var curSelector = null;
 9 
10     //第一轮筛选出来的元素
11     var els = query(arrSelector[len - 1]);
12     //只有一个选择器便直接返回了
13     if (len == 1) return els;
14 
15     while (index != -1) {
16         //获取当前的筛选选择器
17         curSelector = arrSelector[index];
18         var tmpArr = [];
19         for (var i = 0, len = els.length; i < len; i++) {
20             var tmpEl = els[i];
21             if (filter(tmpEl, curSelector))
22                 tmpArr.push(tmpEl);
23         }
24         els = tmpArr;
25         index--;
26     }
27     return els;
28 };
复制代码
④,然后,就没有然后了。。。。
不足与提高
这个代码明显就是玩具,三无产品:
① 无测试
② 无子选择器/兄弟选择器
③ 无性能
但是,以上东西暂时和我无关啦,因为学习嘛。。。。
最后附上师兄选择器代码:
 View Code
然后,就没有然后了。。。
小插曲-浮点数计算
今天项目重遇到一个问题,我和我的小伙伴都惊呆了:
你没有看错,33.1 * 3 就是那么多!!!
尼玛已证明这是一个js的bug,我可以这么说么???
解决方案,求回复(我会说我想骗点回复么???)
 
parseInt(33.1 * 3 * 100) / 100
 
 
本文转自叶小钗博客园博客,原文链接http://www.cnblogs.com/yexiaochai/p/3258279.html,如需转载请自行联系原作者
你可能感兴趣的文章
iOS中 支付宝钱包具体解释/第三方支付 韩俊强的博客
查看>>
solidity代码
查看>>
【转】C++可变参数列表处理宏va_list、va_start、va_end的使用
查看>>
跨站脚本攻击XSS
查看>>
Android Studio 中的FindBugs插件使用,轻松帮你发现Bug (转)
查看>>
linux ls 命令
查看>>
聊一聊PV和并发、以及计算web服务器的数量的方法
查看>>
Win10 IoT C#开发 4 - UART 串口通信
查看>>
UWP入门(一) -- 先写几个简单控件简单熟悉下(别看这个)
查看>>
Spring+CXF整合来管理webservice(服务器启动发布webservice)
查看>>
mysql-5.7 调整mysql的复制方式由master_log_file+master_log_pos 到gtid 详解
查看>>
【转】C++标准转换运算符reinterpret_cast
查看>>
django开发环境部署之pip、virtualenv、virtualenvwrapper
查看>>
css3 animation 在某些浏览器中特别快 bugfix
查看>>
【Android】如何获取本机号码、IMSI、EMSI
查看>>
Python之2维list转置、旋转及其简单应用
查看>>
【Win 10 应用开发】UI Composition 札记(六):动画
查看>>
如何下载合适自己系统环境的Xdebug
查看>>
【转】VC++计算当前时间点间隔N天的时间(不使用CTimeSpan类)
查看>>
gitweb
查看>>