原生的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 相关文章推荐
js自定义事件代码说明
Jan 31 Javascript
createElement与createDocumentFragment的点点区别小结
Dec 19 Javascript
Three.js源码阅读笔记(基础的核心Core对象)
Dec 27 Javascript
jQuery列表拖动排列具体实现
Nov 04 Javascript
JavaScript中的undefined学习总结
Nov 30 Javascript
js实现瀑布流的三种方式比较
Jun 28 Javascript
js for循环倒序输出数组元素的实例
Mar 01 Javascript
利用Plupload.js解决大文件上传问题, 带进度条和背景遮罩层
Mar 15 Javascript
js自定义Tab选项卡效果
Jun 05 Javascript
Vue2仿淘宝实现省市区三级联动
Apr 15 Javascript
Koa日志中间件封装开发详解
Mar 09 Javascript
Vue infinite update loop的问题解决
Apr 23 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
114啦源码(114la)不能生成地方房产和地方报刊问题4级页面0字节的解决方法
2012/01/12 PHP
thinkphp在模型中自动完成session赋值示例代码
2014/09/09 PHP
php使用GD创建保持宽高比缩略图的方法
2015/04/17 PHP
DEDECMS首页调用图片集里的多张图片
2015/06/05 PHP
php 使用mpdf实现指定字段配置字体样式的方法
2019/07/29 PHP
JS获取scrollHeight问题想到的标准问题
2007/05/27 Javascript
通过继承IHttpHandle实现JS插件的组织与管理
2010/07/13 Javascript
微信小程序开发之实现选项卡(窗口顶部TabBar)页面切换
2016/11/25 Javascript
angular-ngSanitize模块-$sanitize服务详解
2017/06/13 Javascript
webpack打包非模块化js的方法
2018/10/24 Javascript
详解js根据百度地图提供经纬度计算两点距离
2019/05/13 Javascript
javascript自定义右键菜单插件
2019/12/16 Javascript
解决vue-loader加载不上的问题
2020/10/21 Javascript
vue element-ul实现展开和收起功能的实例代码
2020/11/25 Vue.js
React中使用Vditor自定义图片详解
2020/12/25 Javascript
Python 命令行参数sys.argv
2008/09/06 Python
Django框架中方法的访问和查找
2015/07/15 Python
python查看FTP是否能连接成功的方法
2015/07/30 Python
详解python开发环境搭建
2016/12/16 Python
python+tkinter编写电脑桌面放大镜程序实例代码
2018/01/16 Python
Python简单计算文件MD5值的方法示例
2018/04/11 Python
Python嵌套列表转一维的方法(压平嵌套列表)
2018/07/03 Python
python实现12306登录并保存cookie的方法示例
2019/12/17 Python
英国最大的香水商店:The Fragrance Shop
2018/07/06 全球购物
日本快乐生活方式购物网站:Shop Japan
2018/07/17 全球购物
Calzedonia美国官网:意大利风格袜子、打底裤和沙滩装
2018/07/19 全球购物
英国羊皮鞋类领先品牌:Just Sheepskin
2019/12/12 全球购物
亚洲最大的运动鞋寄售店:KicksCrew
2020/11/26 全球购物
中软Java笔试题
2012/11/11 面试题
小学教师师德演讲稿
2014/05/06 职场文书
本科毕业论文指导教师评语
2014/12/30 职场文书
给客户的感谢信
2015/01/21 职场文书
家长意见书
2015/06/04 职场文书
培训学校2015年度工作总结
2015/07/20 职场文书
MySQL中order by的使用详情
2021/11/17 MySQL
MongoDB使用场景总结
2022/02/24 MongoDB