原生的html元素选择器类似jquery选择器


Posted in Javascript onOctober 15, 2014

做前端,需要选择元素,虽说有jquery和各大js库已经帮我造好了轮子,但我想试试自己实现一个,正好项目也不忙,正好加入自己的js文件中,下面是实现代码。用$g(“#content .op”)这种格式就可以调用,和jquery $()的参数一样:

function $findChilds(parentNode, text) 
{ 
//如果不传入父节点的话,默认为body 
if(parentNode == undefined) 
parentNode = document.body; 
var childNodes = parentNode.childNodes; 
var results = []; 
//子节点大于零才循环 
if(childNodes.length > 0) 
{ 
var length = childNodes.length; 
//循环查找符合text的节点 
for(var i=0;i<length;++i) 
{ 
//三种情况,className,id, tagName 
switch(text.substr(0, 1)) 
{ 
case '.': 
//这两种:parentNode.getElementsByClassName,parentNode.all 
//都是后来加上的,如果浏览器这两种方法都不支持,那就只能暴力递归了 
if(parentNode.getElementsByClassName) 
return parentNode.getElementsByClassName(text.substr(1)); 
else if(parentNode.all) 
{ 
var finded = []; 
var jlength = parentNode.all.length; 
for(var j=0;j<jlength;++j) 
if(parentNode.all[j].className == text.substr(1)) 
finded.push(parentNode.all[j]); 
return finded; 
} 
//以上两种方法都不支持,直接判断 
if(childNodes[i].className == text.substr(1)) 
results.push(childNodes[i]); 
break; 
case '#': 
return [document.getElementById(text.substr(1))]; 
default: 
return parentNode.getElementsByTagName(text); 
} 
//判断完后,把当前子元素的子元素传入$findChilds进行递归查找,返回的结果直接和现在的结果合并 
results = results.concat($findChilds(childNodes[i], text)); 
} 
} 
return results; 
} 

String.prototype.vtrim = function() { 
return this.replace(/^\s+|\s+$/g, ''); 
} 

function $g(text) 
{ 
//按照空格分割参数 
var values = text.vtrim().split(" "); 
var length = values.length; 
//如果只有一个选择参数的话,就直接调用dom方法返回结果。 
if(length == 1) 
switch(values[0].substr(0, 1)) 
{ 
case "#": 
return document.getElementById(values[0].substr(1)); 
case ".": 
if(document.getElementsByClassName) 
return document.getElementsByClassName(values[0].substr(1)); 
default: 
return document.getElementsByTagName(values[0]); 
} 
//每次迭代都会产生许多符合参数的结果节点,这里结果节点的名称为parentNodes,第一次循环默认为body 
var parentNodes = [document.body]; 
//外层循环为迭代每个传入的参数 
for(var i = 0; i < length; ++i) 
{ 
var jlength = parentNodes.length; 
var results = []; 
//这里如果values的长度为零的话, 
//就说明是多出来的空格, 
//例如:$g(" .content");这种情况不执行代码直接跳入下一循环 
var tmpValue = values[i].vtrim(); 
if(tmpValue.length <= 0) 
continue; 
//内层循环为迭代每个结果节点, 
//在结果节点中查找符合选择条件的结果。当然第一次为body 
for(var j=0;j<jlength;++j) 
{ 
//$findChilds就是上边的那个函数,就是选择某个节点的子节点的 
var result = $findChilds(parentNodes[j], values[i].vtrim()); 
var rlength = result.length; 
//因为返回的有时候是html容器,无法直接和数组concat所以倒入数组,这里有优化空间,但暂不考虑性能先这么做 
for (var k = 0; k < rlength; ++k) 
results.push(result[k]); 
} 
//没有结果,立即返回undefined 
if(results == undefined || results.length <= 0) 
return undefined; 
//最后一次循环就直接返回结果数组,但是如果最后一个选择条件是选择id的话,那就不返回数组直接返回dom对象了 
if (i == length - 1) 
{ 
if (values[i].substr(0, 1) == "#") 
return results[0]; 
return results; 
} 
parentNodes = results; 
} 
}

经过在ff ie6下的测试 单纯的选择id比jquery要快很多,
其他的部分选择模式我测试的少数比jquery要快。
当然测试不可能全面,还可能会有bug,而且不支持类似于.content:first-child这样的伪类选择。

Javascript 相关文章推荐
XmlUtils JS操作XML工具类
Oct 01 Javascript
JS+XML 省份和城市之间的联动实现代码
Oct 14 Javascript
jQuery实现瀑布流布局详解(PC和移动端)
Sep 01 Javascript
基于jQuery实现的打字机效果
Jan 16 Javascript
jQuery判断邮箱格式对错实例代码讲解
Apr 12 jQuery
highcharts 在angular中的使用示例代码
Sep 20 Javascript
VueRouter导航守卫用法详解
Dec 25 Javascript
JS求Number类型数组中最大元素方法
Apr 08 Javascript
Element Input组件分析小结
Oct 11 Javascript
Element中的Cascader(级联列表)动态加载省\市\区数据的方法
Mar 27 Javascript
使用axios发送post请求,将JSON数据改为form类型的示例
Oct 31 Javascript
jquery选择器和属性对象的操作实例分析
Jan 10 jQuery
用原生JS获取CLASS对象(很简单实用)
Oct 15 #Javascript
通过JS动态创建一个html DOM元素并显示
Oct 15 #Javascript
javascript模拟实现ajax加载框实例
Oct 15 #Javascript
jquery幻灯片插件bxslider样式改进实例
Oct 15 #Javascript
微信分享的标题、缩略图、连接及描述设置方法
Oct 14 #Javascript
js实现select组件的选择输入过滤代码
Oct 14 #Javascript
javascript记录文本框内文字个数检测文字个数变化
Oct 14 #Javascript
You might like
BBS(php &amp; mysql)完整版(三)
2006/10/09 PHP
PHP is_dir() 判断给定文件名是否是一个目录
2010/05/10 PHP
php数组编码转换示例详解
2014/03/11 PHP
php使用ob_start()实现图片存入变量的方法
2014/11/14 PHP
PHP封装的数据库模型Model类完整示例【基于PDO】
2019/03/14 PHP
innerHTML,outerHTML,innerTEXT三者之间的区别
2007/01/28 Javascript
利用百度地图JSAPI生成h7n9禽流感分布图实现代码
2013/04/15 Javascript
如何学习Javascript入门指导
2013/11/01 Javascript
浅析基于WEB前端页面的页面内容搜索的实现思路
2014/06/10 Javascript
javascript实现复选框超过限制即弹出警告框的方法
2015/02/25 Javascript
javascript实现数独解法
2015/03/14 Javascript
Bootstrap项目实战之子栏目资讯内容
2016/04/25 Javascript
js实现当鼠标移到表格上时显示这一格全部内容的代码
2016/06/12 Javascript
js拖动滑块和点击水波纹效果实例代码
2018/10/16 Javascript
实现Vue的markdown文档可以在线运行的方法示例
2018/12/11 Javascript
js删除数组中某几项的方法总结
2019/01/16 Javascript
JS实现的新闻列表自动滚动效果示例
2019/01/30 Javascript
原来JS还可以这样拆箱转换详解
2019/02/01 Javascript
如何修改Vue打包后文件的接口地址配置的方法
2020/04/22 Javascript
vue监听键盘事件的相关总结
2021/01/29 Vue.js
[57:55]完美世界DOTA2联赛PWL S3 Magma vs Phoenix 第二场 12.12
2020/12/16 DOTA
[58:29]DOTA2-DPC中国联赛 正赛 Phoenix vs XG BO3 第一场 1月31日
2021/03/11 DOTA
python打开文件并获取文件相关属性的方法
2015/04/23 Python
Python使用CMD模块更优雅的运行脚本
2015/05/11 Python
Python3实现发送QQ邮件功能(html)
2017/12/15 Python
Flask框架Jinjia模板常用语法总结
2018/07/19 Python
python制作简单五子棋游戏
2019/06/18 Python
Desigual英国官网:在线购买原创服装
2018/03/09 全球购物
屈臣氏乌克兰:Watsons UA
2019/10/29 全球购物
毕业生求职简历的自我评价
2013/10/07 职场文书
卖房协议书样本
2014/10/30 职场文书
师范生见习报告范文
2014/11/03 职场文书
2014年餐厅服务员工作总结
2014/11/18 职场文书
2014年城管个人工作总结
2014/12/08 职场文书
七年级思品教学反思
2016/02/20 职场文书
Go标准容器之Ring的使用说明
2021/05/05 Golang