JS封装简单后代选择器
大概思路是这样的:通过判断传过来的参数是什么类型,如果是对象,那这里就是this(因为封装是自己用的,肯定不会随便乱传一个对象过来),如果是一个函数(匿名函数),那就是Dom加载(这里先不讲),如果是字符串,那就是CSS选择器,通过判断是否存在空格,没有就是单一CSS选择器,有就是后代选择器。然后再通过判断是ID选择器,类选择器还是元素选择器来执行具体的操作:
这里创建一个构造函数实现基础库Jr :
function Jr(){ }
在其原型上添加方法:
//获取ID节点
Jr.prototype.getId = function(id){
return document.getElementById(id);
} //获取CLASS节点数组
Jr.prototype.getClass = function(className, parentNode){
var node = null; //存放父节点
var temps = [];
if(parentNode != undefined){ //存在父节点时
node = parentNode;
} else { //不存在则默认document
node = document;
}
var all = node.getElementsByTagName('*');
for(var i = 0; i < all.length; i++){
//遍历所有节点,判断是否有包含className
if((new RegExp('(\\s|^)' + className + '(\\s|$)')).test(all[i].className)){
temps.push(all[i]);
}
}
return temps;
} //获取元素节点数组
Jr.prototype.getTagName = function(tag, parentNode){
var node = null; //存放父节点
var temps = [];
if(parentNode != undefined){
node = parentNode;
} else {
node = document;
}
var tags = node.getElementsByTagName(tag);
for(var i = 0; i < tags.length; i++){
temps.push(tags[i]);
}
return temps;
}
接下来就是在构造函数里通过传参来进行一系列选择器操作:
//基础库
function Jr(args){
//创建一个数组,用来保存获取的节点或节点数组
this.elements = [];
//当参数是一个字符串,说明是常规css选择器,不是this,或者function
if(typeof args == 'string'){
//css模拟,就是跟CSS后代选择器一样
if(args.indexOf(' ') != -1){
//把节点拆分开并保存在数组里
var elements = args.split(' ');
//存放临时节点对象的数组,解决被覆盖问题
var childElements = [];
var node = []; //用来存放父节点用的
for(var i = 0; i < elements.length; i++){
//如果默认没有父节点,就指定document
if(node.length == 0) node.push(document);
switch(elements[i].charAt(0)) {
//id
case '#' :
//先清空临时节点数组
childElements = [];
childElements.push(this.getId(elements[i].substring(1)));
node = childElements; //保存到父节点
break;
//类
case '.' :
childElements = [];
//遍历父节点数组,匹配符合className的所有节点
for(var j = 0; j < node.length; j++){
var temps = this.getClass(elements[i].substring(1), node[j]);
for(var k = 0; k < temps.length; k++){
childElements.push(temps[k]);
}
}
node = childElements;
break;
//标签
default :
childElements = [];
for(var j = 0; j < node.length; j++){
var temps = this.getTagName(elements[i], node[j]);
for(var k = 0; k < temps.length; k++){
childElements.push(temps[k]);
}
}
node = childElements; }
}
this.elements = childElements;
} else {
//find模拟,就是说只是单一的选择器
switch(args.charAt(0)) {
case '#':
this.elements.push(this.getId(args.substring(1)));
break;
case '.':
this.elements = this.getClass(args.substring(1));
break;
default :
this.elements = this.getTagName(args);
}
}
} else if(typeof args == 'Object'){
if(args != undefined){
this.elements[0] = args;
}
} else if(typeof args == 'function'){
//这里不讲
this.ready(args);
}
}
最后,我们调用该基础库:
//调用
var $ = function(args){
return new Jr(args);
}
现在,我们就可以实现如下选择器等效果了:
$(this)
$('#box')
$('.box')
$('div')
$('#box div .nav')
$('.box .nav p')
JS封装简单后代选择器的更多相关文章
- 原生JS封装简单动画效果
原生JS封装简单动画效果 一致使用各种插件,有时候对原生JS陌生了起来,所以决定封装一个简单动画效果,熟悉JS原生代码 function animate(obj, target,num){ if(ob ...
- 关于js封装框架类库之选择器引擎(二)
在上篇介绍了选择器的获取标签.id.类名的方法,现在我们在上篇基础上继续升级 1.问题描述:上篇get('选择器')已经实现,如果get方法里是一个选择器的父元素,父元素是DOM对象,那么如何获取元素 ...
- JS的简单用法
JS的简单用法 参考:http://www.w3school.com.cn/js/js_switch.asp JavaScript 是网络的脚本语言 JavaScript 是可插入 HTML 页面的编 ...
- 第一百三十九节,JavaScript,封装库--CSS选择器
JavaScript,封装库--修改元素选择器 就是将构造库函数修改成元素选择器,像css那样,输入#xxx .xxx xxx (获取指定id下的指定class下的指定标签元素) 修改后的基础库 / ...
- jQuery---jq基础了解(语法,特性),JQ和JS的区别对比,JQ和JS相互转换,Jquery的选择器(基础选择器,层级选择器,属性选择器),Jquery的筛选器(基本筛选器,表单筛选器),Jquery筛选方法
jQuery---jq基础了解(语法,特性),JQ和JS的区别对比,JQ和JS相互转换,Jquery的选择器(基础选择器,层级选择器,属性选择器),Jquery的筛选器(基本筛选器,表单筛选器),Jq ...
- 原生JS封装Ajax插件(同域&&jsonp跨域)
抛出一个问题,其实所谓的熟悉原生JS,怎样的程度才是熟悉呢? 最近都在做原生JS熟悉的练习... 用原生Js封装了一个Ajax插件,引入一般的项目,传传数据,感觉还是可行的...简单说说思路,如有不正 ...
- 使用NW.js封装微信公众号菜单编辑器为桌面应用
开发微信公众号的朋友都会遇到一个常见的需求就是修改自定义菜单,如果每个人都去开发这个不经常使用的功能确实有点浪费时间.前段时间在github上找到一个仿企业号的菜单编辑界面,结合微信的C# SDK开发 ...
- 用jQuery基于原生js封装的轮播
我发现轮播在很多网站里面都用到过,一个绚丽的轮播可以为网页增色不少,最近闲来无事,也用原生js封装了一个轮播,可能不像网上的插件那么炫,但是也有用心去做.主要用了闭包的思想.需要传递的参数有:图片地址 ...
- 【学】jQuery的源码思路1——后代选择器
jQuery的源码思路1--后代选择器 这里探讨一下jQuery中后代选择器的封装原理,并自己写一下 getEle('#div1 ul li .box');接受的参数就是个后代选择器,类似于这样: # ...
随机推荐
- 巡风代码架构简介以及Flask的项目文件结构简介
一.巡风: 巡风是一款什么东西,想必安全同行都不陌生吧.用它作为内网漏洞扫描管理架构是一种很好的选择,扫描快,开源,还可自己编写符合规则的POC直接放入相应目录来扩展.今天下午趁着有点时间捋了一下巡风 ...
- thinkCMF的使用!
第一次使用 thinkCMF:在此记录下使用的过程! 后台登录: http://thinkcmf.fyz.com/public/admin 前台:控制器 前台控制器的模板:
- OneThink视图模型进行组合查询!文档组合文档详情
测试方法:twoCate: public function twoCate(){ $where = array( 'category_id'=>43 ); $list = D('TwoView' ...
- php 判断变量函数
1.isset功能:判断变量是否被初始化 判断变量是否被定义了 2.empty功能:检测变量是否为"空" 说明:任何一个未初始化的变量.值为 0 或 false 或 空字符串&qu ...
- poj3345 Bribing FIPA【树形DP】【背包】
Bribing FIPA Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5910 Accepted: 1850 Desc ...
- HDU1530 Maximum Clique dp
正解:dp 解题报告: 这儿是传送门 又是个神仙题趴QAQ 这题就直接说解法辣?主要是思想比较难,真要说有什么不懂的知识点嘛也没有,所以也就没什么好另外先提一下的知识点QAQ 首先取反,就变成了求最大 ...
- Ubuntu18.04 英文系统下安装中文输入法
今天尝试了Ubuntu18.04LTS(依旧装的英文版)发现按照之前的方法( http://www.cnblogs.com/asmer-stone/p/5227188.html)安装中文输入法不行了, ...
- android 错误收集
2. is not translated in Eclipse > Preference > Android > Lint Error Checking的Correctness: M ...
- HTTP错误 404.17–Not Found 请求的内容似乎是脚本,因而将无法有静态文件处理程序来处理
解决方案:切换应用程序池的模式.
- node-schedule 实现定时任务使用方法记录
在项目中有个每天0点执行的函数,本来想用setInterval来实现,但觉得这种需求以后应该还会有,自己写可能拓展性不高.搜了一下发现了node-schedule这个包.现在记录一下使用方法 node ...