原生的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 相关文章推荐
Firefox和IE浏览器兼容JS脚本写法小结
Jul 07 Javascript
JavaScript根据数据生成百分比图和柱状图的实例代码
Jul 14 Javascript
js替换字符串的所有示例代码
Jul 23 Javascript
从零学JS之你需要了解的几本书
May 19 Javascript
javascript运算符语法全面概述
Jul 14 Javascript
详解Node.Js如何处理post数据
Sep 19 Javascript
JavaScript组成、引入、输出、运算符基础知识讲解
Dec 08 Javascript
JS对象的深度克隆方法示例
Mar 16 Javascript
jQuery中 DOM节点操作方法大全
Oct 12 jQuery
layui关闭弹窗后刷新主页面和当前更改项的例子
Sep 06 Javascript
小程序新版订阅消息模板消息
Dec 31 Javascript
jQuery实现计算器功能
Oct 19 jQuery
用原生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
mac下安装nginx和php
2013/11/04 PHP
PHP实现模仿socket请求返回页面的方法
2014/11/04 PHP
PHP中file_get_contents函数抓取https地址出错的解决方法(两种方法)
2015/09/22 PHP
php 开发中加密的几种方法总结
2017/03/22 PHP
thinkPHP5框架分页样式类完整示例
2018/09/01 PHP
javascript下对于事件、事件流、事件触发的顺序随便说说
2010/07/17 Javascript
jQuery性能优化28条建议你值得借鉴
2013/02/16 Javascript
JavaScript实现Flash炫光波动特效
2015/05/14 Javascript
微信开发 消息推送实现代码
2016/10/21 Javascript
ECMAScript6变量的解构赋值实例详解
2017/09/19 Javascript
基于casperjs和resemble.js实现一个像素对比服务详解
2018/01/10 Javascript
vue-router重定向和路由别名的使用讲解
2019/01/19 Javascript
微信公众平台 发送模板消息(Java接口开发)
2019/04/17 Javascript
微信小程序实现导航栏和内容上下联动功能代码
2020/06/29 Javascript
基于python编写的微博应用
2014/10/17 Python
python中通过预先编译正则表达式提高效率
2017/09/25 Python
python使用tkinter实现简单计算器
2018/01/30 Python
Python回文字符串及回文数字判定功能示例
2018/03/20 Python
python+POP3实现批量下载邮件附件
2018/06/19 Python
python使用writerows写csv文件产生多余空行的处理方法
2019/08/01 Python
python字符串,元组,列表,字典互转代码实例详解
2020/02/14 Python
Python3变量与基本数据类型用法实例分析
2020/02/14 Python
使用Python+selenium实现第一个自动化测试脚本
2020/03/17 Python
python如何求100以内的素数
2020/05/27 Python
pandas之分组groupby()的使用整理与总结
2020/06/18 Python
python3通过subprocess模块调用脚本并和脚本交互的操作
2020/12/05 Python
pandas抽取行列数据的几种方法
2020/12/13 Python
两种CSS3伪类选择器详细介绍
2013/12/24 HTML / CSS
纯CSS3单页切换导航菜单界面设计的简单实现
2016/08/16 HTML / CSS
法国娇韵诗官方旗舰店:Clarins是来自法国的天然护肤品牌
2018/06/30 全球购物
澳大利亚手表品牌:Time IV Change
2018/10/06 全球购物
Eagle Eyes Optics鹰眼光学:高性能太阳镜
2018/12/07 全球购物
留学经费担保书
2014/05/12 职场文书
学生实习证明模板汇总
2014/09/25 职场文书
2014年超市工作总结
2014/11/19 职场文书
SpringDataJPA实体类关系映射配置方式
2021/12/06 Java/Android