原生的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 相关文章推荐
在修改准备发的批量美化select+可修改select时,在非IE下发现了几个问题
Jan 09 Javascript
js控制input输入字符解析
Dec 27 Javascript
把字符串按照特定的字母顺序进行排序的js代码
Jan 28 Javascript
JavaScript中for循环的使用详解
Jun 03 Javascript
详解JavaScript的表达式与运算符
Nov 30 Javascript
PhotoSwipe异步动态加载图片方法
Aug 25 Javascript
JS 组件系列之 bootstrap treegrid 组件封装过程
Apr 28 Javascript
js实现放大镜特效
May 18 Javascript
vue-router路由懒加载和权限控制详解
Dec 13 Javascript
JS实现十分钟倒计时代码实例
Oct 18 Javascript
Vue中通过vue-router实现命名视图的问题
Apr 23 Javascript
Vue自定义render统一项目组弹框功能
Jun 07 Javascript
用原生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
JAVA/JSP学习系列之二
2006/10/09 PHP
php XPath对XML文件查找及修改实现代码
2011/07/27 PHP
phpmail类发送邮件函数代码
2012/02/20 PHP
php5.3 不支持 session_register() 此函数已启用的解决方法
2013/11/12 PHP
php中随机函数mt_rand()与rand()性能对比分析
2014/12/01 PHP
SSO单点登录的PHP实现方法(Laravel框架)
2016/03/23 PHP
php指定长度分割字符串str_split函数用法示例
2017/01/30 PHP
JavaScript 字符串乘法
2009/08/20 Javascript
jQuery中获取checkbox选中项等操作及注意事项
2013/11/24 Javascript
jQuery中clone()方法用法实例
2015/01/16 Javascript
超级给力的JavaScript的React框架入门教程
2015/07/02 Javascript
Javascript实现的简单右键菜单类
2015/09/23 Javascript
Bootstrap Table的使用总结
2016/10/08 Javascript
Vue.js bootstrap前端实现分页和排序
2017/03/10 Javascript
关于foreach循环中遇到的问题小结
2017/05/08 Javascript
详解SPA中前端路由基本原理与实现方式
2018/09/12 Javascript
Vue项目中使用WebUploader实现文件上传的方法
2019/07/21 Javascript
详解基于Vue/React项目的移动端适配方案
2019/08/23 Javascript
微信小程序的引导页实现代码
2020/06/24 Javascript
js实现验证码干扰(动态)
2021/02/23 Javascript
Python远程桌面协议RDPY安装使用介绍
2015/04/15 Python
Python实现查找匹配项作处理后再替换回去的方法
2017/06/10 Python
pandas通过loc生成新的列方法
2018/11/28 Python
浅谈Python小波分析库Pywavelets的一点使用心得
2019/07/09 Python
解决Python安装时报缺少DLL问题【两种解决方法】
2019/07/15 Python
使用python代码进行身份证号校验的实现示例
2019/11/21 Python
使用Keras画神经网络准确性图教程
2020/06/15 Python
Python Pandas数据分析工具用法实例
2020/11/05 Python
兰兰过桥教学反思
2014/02/08 职场文书
期末评语大全
2014/05/04 职场文书
实验室标语
2014/06/21 职场文书
业务员岗位职责范本
2015/04/03 职场文书
2015年依法治校工作总结
2015/07/27 职场文书
利用javaScript处理常用事件详解
2021/04/14 Javascript
USB TYPE-C 或将成为所有智能手机充电标准
2022/04/21 数码科技
Win11怎么添加用户?Win11添加用户账户的方法
2022/07/15 数码科技