原生的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读取cookies信息(记录用户名)
Jan 10 Javascript
浅谈JavaScript function函数种类
Dec 29 Javascript
JQuery判断radio(单选框)是否选中和获取选中值方法总结
Apr 15 Javascript
第三篇Bootstrap网格基础
Jun 21 Javascript
jquery replace方法去空格
May 08 jQuery
vue组件watch属性实例讲解
Nov 07 Javascript
vuejs实现标签选项卡动态更改css样式的方法
May 31 Javascript
jsonp跨域获取数据的基础教程
Jul 01 Javascript
React组件重构之嵌套+继承及高阶组件详解
Jul 19 Javascript
解决IE11 vue +webpack 项目中数据更新后页面没有刷新的问题
Sep 25 Javascript
微信小程序网络层封装的实现(promise, 登录锁)
May 08 Javascript
Javascript作用域和作用域链原理解析
Mar 03 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
采用thinkphp自带方法生成静态html文件详解
2014/06/13 PHP
php实现面包屑导航例子分享
2015/12/19 PHP
ThinkPHP实现静态缓存和动态缓存示例代码
2017/05/02 PHP
laravel Task Scheduling(任务调度)在windows下的使用详解
2019/10/22 PHP
JavaScript事件列表解说
2006/12/22 Javascript
常用一些Javascript判断函数
2012/08/14 Javascript
jquery(hide方法)隐藏指定元素实例
2013/11/11 Javascript
Jquery实现遮罩层的方法
2015/06/08 Javascript
Node.js配合node-http-proxy解决本地开发ajax跨域问题
2016/08/31 Javascript
vue实现可增删查改的成绩单
2016/10/27 Javascript
jQuery点击头像上传并预览图片
2017/02/23 Javascript
nodejs利用ajax实现网页无刷新上传图片实例代码
2017/06/06 NodeJs
JS实现网页抢购功能(触发,终止脚本)
2017/11/27 Javascript
Dropify.js图片宽高自适应的方法
2017/11/27 Javascript
详解使用mpvue开发github小程序总结
2018/07/25 Javascript
iview form清除校验状态的实现
2019/09/19 Javascript
vue+iview框架实现左侧动态菜单功能的示例代码
2020/07/23 Javascript
Vue+Vant 图片上传加显示的案例
2020/11/03 Javascript
js中延迟加载和预加载的具体使用
2021/01/14 Javascript
Python文件右键找不到IDLE打开项解决办法
2015/06/08 Python
浅谈pycharm下找不到sqlalchemy的问题
2018/12/03 Python
python多线程并发让两个LED同时亮的方法
2019/02/18 Python
Python 一键制作微信好友图片墙的方法
2019/05/16 Python
python PyAutoGUI 模拟鼠标键盘操作和截屏功能
2019/08/04 Python
Centos7下源码安装Python3 及shell 脚本自动安装Python3的教程
2020/03/07 Python
socket.io 和canvas 实现的共享画板功能
2019/05/22 HTML / CSS
广州品高软件.net笔面试题目
2012/04/18 面试题
数控技术与应用毕业生自荐信
2013/09/24 职场文书
高中生的自我鉴定范文
2014/01/24 职场文书
海洋科学专业求职信
2014/08/10 职场文书
八项规定整改方案
2014/10/01 职场文书
借条格式范本
2015/05/25 职场文书
新年晚会开场白
2015/05/29 职场文书
运动员代表致辞
2015/07/29 职场文书
小学班级口号大全
2015/12/25 职场文书
巾帼建功标兵先进事迹材料
2016/02/29 职场文书