原生的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 相关文章推荐
利用404错误页面实现UrlRewrite的实现代码
Aug 20 Javascript
javascript 尚未实现错误解决办法
Nov 27 Javascript
jquery 日期控件datepicker属性详细解析
Nov 08 Javascript
实例讲解jquery与json的结合
Jan 07 Javascript
JS简单实现仿百度控制台输出信息效果
Sep 04 Javascript
轻松理解JavaScript之AJAX
Mar 15 Javascript
Angular 4根据组件名称动态创建出组件的方法教程
Nov 01 Javascript
angular 内存溢出的问题解决
Jul 12 Javascript
全面解析vue router 基本使用(动态路由,嵌套路由)
Sep 02 Javascript
超好用的jQuery分页插件jpaginate用法示例【附源码下载】
Dec 06 jQuery
JS函数进阶之prototy用法实例分析
Jan 15 Javascript
webstorm建立vue-cli脚手架的傻瓜式教程
Sep 22 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中的字符串函数
2006/11/24 PHP
上传多个文件的PHP脚本
2006/11/26 PHP
提高代码性能技巧谈—以创建千行表格为例
2006/07/01 Javascript
JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] )
2011/02/25 Javascript
jquery刷新页面的实现代码(局部及全页面刷新)
2011/07/11 Javascript
JS实现图片预加载无需等待
2012/12/21 Javascript
使用js修改客户端注册表的方法
2013/08/09 Javascript
JavaScript的MVVM库Vue.js入门学习笔记
2016/05/03 Javascript
JS使用eval()动态创建变量的方法
2016/06/03 Javascript
JS中去掉array中重复元素的方法
2017/05/26 Javascript
js+html5实现复制文字按钮
2017/07/15 Javascript
Vue编写多地区选择组件
2017/08/21 Javascript
原生js调用json方法总结
2018/02/22 Javascript
JavaScript 日期时间选择器一些小结
2018/04/02 Javascript
三种Webpack打包方式(小结)
2018/09/19 Javascript
微信小程序入口场景的问题集合与相关解决方法
2019/06/26 Javascript
浅入深出Vue之组件使用
2019/07/11 Javascript
在Python中操作文件之read()方法的使用教程
2015/05/24 Python
Python的消息队列包SnakeMQ使用初探
2016/06/29 Python
查看TensorFlow checkpoint文件中的变量名和对应值方法
2018/06/14 Python
djano一对一、多对多、分页实例代码
2019/08/16 Python
将matplotlib绘图嵌入pyqt的方法示例
2020/01/08 Python
python 回溯法模板详解
2020/02/26 Python
基于Python fminunc 的替代方法
2020/02/29 Python
django 链接多个数据库 并使用原生sql实现
2020/03/28 Python
Keras - GPU ID 和显存占用设定步骤
2020/06/22 Python
利用PyQt5+Matplotlib 绘制静态/动态图的实现代码
2020/07/13 Python
python如何编写类似nmap的扫描工具
2020/11/06 Python
html5的canvas方法使用指南
2014/12/15 HTML / CSS
纬创Java面试题笔试题
2014/10/02 面试题
硕士研究生就业推荐信
2014/05/18 职场文书
中学生检讨书1000字
2014/10/28 职场文书
北京天坛导游词
2015/02/12 职场文书
军事博物馆观后感
2015/06/05 职场文书
php中pcntl_fork详解
2021/04/01 PHP
Python初识逻辑与if语句及用法大全
2021/08/07 Python