原生的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 相关文章推荐
jquery UI 1.72 之datepicker
Dec 29 Javascript
jQuery获取当前对象标签名称的方法
Feb 07 Javascript
jquery插件冲突(jquery.noconflict)解决方法分享
Mar 20 Javascript
js代码实现随机颜色的小方块
Jul 30 Javascript
浅谈jQuery效果函数
Sep 16 Javascript
canvas绘图不清晰的解决方案
Feb 28 Javascript
jQuery Chosen通用初始化
Mar 07 Javascript
ajax+node+request爬取网络图片的实例(宅男福利)
Aug 28 Javascript
vue主动刷新页面及列表数据删除后的刷新实例
Sep 16 Javascript
vue使用Google地图的实现示例代码
Dec 19 Javascript
原生js实现下拉框选择组件
Jan 20 Javascript
深入详解JS函数的柯里化
Jun 09 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
php db类库进行数据库操作
2009/03/19 PHP
PHP实现长文章分页实例代码(附源码)
2016/02/03 PHP
PHP实现的AES加密、解密封装类与用法示例
2018/08/02 PHP
Js+php实现异步拖拽上传文件
2015/06/23 Javascript
JS使用cookie设置样式的方法
2016/06/30 Javascript
JavaScript中this的四个绑定规则总结
2016/09/26 Javascript
AngularJS中的DOM操作用法分析
2016/11/04 Javascript
node.js实现回调的方法示例
2017/03/01 Javascript
Vue resource中的GET与POST请求的实例代码
2017/07/21 Javascript
Vue实例中生命周期created和mounted的区别详解
2017/08/25 Javascript
p5.js入门教程之鼠标交互的示例
2018/03/16 Javascript
js统计页面上每个标签的数量实例代码
2018/05/29 Javascript
video.js 一个页面同时播放多个视频的实例代码
2018/11/27 Javascript
微信小程序sessionid不一致问题解决
2019/08/30 Javascript
js实现div色块拖动录制
2020/01/16 Javascript
[03:44]2015国际邀请赛选手档案—Cloud9.NoTail
2015/07/28 DOTA
使用基于Python的Tornado框架的HTTP客户端的教程
2015/04/24 Python
python机器学习之神经网络实现
2018/10/13 Python
python requests.post带head和body的实例
2019/01/02 Python
提升Python程序性能的7个习惯
2019/04/14 Python
Python datetime 格式化 明天,昨天实例
2020/03/02 Python
如何基于python实现不邻接植花
2020/05/01 Python
aws 通过boto3 python脚本打pach的实现方法
2020/05/10 Python
Python日志器使用方法及原理解析
2020/09/27 Python
一款恶搞头像特效的制作过程 利用css3和jquery
2014/11/21 HTML / CSS
css 如何让背景图片拉伸填充避免重复显示
2013/07/11 HTML / CSS
Html5页面上如何禁止手机虚拟键盘弹出
2020/03/19 HTML / CSS
帕克纽约:PARKER NY
2018/12/09 全球购物
万户网络JAVA程序员岗位招聘笔试试卷
2013/01/08 面试题
迟到早退检讨书
2014/02/10 职场文书
维护民族团结演讲稿
2014/08/27 职场文书
乡镇创先争优活动总结
2014/08/28 职场文书
乡镇党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
单位作风建设自查报告
2014/10/23 职场文书
事业单位年度考核评语
2014/12/31 职场文书
MySQL数据库配置信息查看与修改方法详解
2022/06/25 MySQL