关于js封装框架类库之选择器引擎(一)
选择器模块之传统做法
var tag = function (tag){
return document.getElementsByTagName(tag);
}
var id = function (id){
return document.getElementById(id);
}
var className = function (className){
return document.getElementsByClassName(className);
}
由浅入深之tag方法
这是html部分代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
div, p {
width: 200px;
height:50px;
border:1px dashed red;
margin: 10px 0;
}
</style>
</head>
<body>
<div></div>
<div></div>
<p></p>
<p></p>
</body>
//例如给div盒子添加背景色我们可能会这么做
var divs = tag('div');
var each = function (arr){
for(var i = 0;i< arr.length;i++){
arr[i].style.backgroundColor = 'pink';
}
}
each(divs);
//也可能会这么做
var list = tag('div');
var each = function (arr,fn){
for(var i = 0;i<arr.length;i++){
if(fn.call(arr[i],i,arr[i]) === false ){//等于false时,终止循环
break;
}
}
}
each(list,function(){
this.style.backgroundColor = 'yellow';
})
//上式的fn.call(arr[i],i,arr[i]) === false,下面函数也用到这种调用方式,可以做下比较
var arr = [ 1, 2, 3, 4, 3, 5];
var each = function ( arr, fn ) {
for ( var i = 0; i < arr.length; i++ ) {
if ( fn( i, arr[ i ] ) === false ) {
break;
}
}
}; var index = -1;
each( arr, function ( i, v ) {
if ( v === 3 ) {
index = i;
return false;//若是break 遍历不会终止 直到遍历完
}
} );
console.log( index );//
/*var tag = function (tag){
return document.getElementsByTagName(tag);
}*/
//以上这种写法的缺点是每次获得元素后又要返回,以至于造成浏览器性能的损耗
//为了简化开发,可以将获得的数组合并到一个数组中,这也是jq中所用到的
var getTag = function ( tag, results ) {
results = results || [];
results.push.apply( results, document.getElementsByTagName( tag ) );
return results;
};
var list = getTag('div');
list = getTag('p',list);//如果再获得p标签,可以这么写
var each = function (arr,fn){
for(var i = 0;i<arr.length;i++){
if(fn.call(arr[i],i,arr[i]) === false ){//等于false时,终止循环
break;
}
}
}
/*each(list,function(){
this.style.backgroundColor = 'lightgreen';
})*/
each(getTag('p',getTag('div')),function(){
this.style.backgroundColor = 'lightgreen';
})
进一步整合以上方法 上面方法也只能获得指定标签元素,需求是要兼顾获取标签、id和类名
思路:单独写一个函数,如果再函数中想获得标签、id和类名,直接调用其方法即可
在此用到的html和样式对以下操作的验证
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
div, p {
width: 200px;
height:50px;
border:1px dashed red;
margin: 10px 0;
}
</style>
</head>
<body>
<div id="id">id</div>
<div class="class"></div>
<p></p>
<p></p>
</body>
1、分别列出获取标签、id、类名对应的方法
var getTag = function ( tag, results ) {
results = results || [];
results.push.apply( results, document.getElementsByTagName( tag ));
return results;
}; var getId = function ( id, results ) {
results = results || [];
results.push( document.getElementById( id ) );//此处是单个数据,无须用apply方法
return results;
}; var getClass = function ( className, results ) {
results = results || [];
results.push.apply( results, document.getElementsByClassName( className ) );
return results;
};
2、书写get方法,判断调用以上哪一种方法
var get = function ( selector, results ) {
results = results || [];
// 1 2 3 4
var rquickExpr = /^(?:#([\w-]+)|\.([\w-]+)|([\w]+)|(\*))$/,//正则表达式
m = rquickExpr.exec( selector );//正则匹配
if ( m ) {//判断是否匹配成功(此处if判断可以省略)
if ( m[ 1 ] ) {
results = getId( m[ 1 ], results );
} else if ( m[ 2 ] ) {
results = getClass( m[ 2 ], results );
} else if ( m[ 3 ] ) {
results = getTag( m[ 3 ], results );
} else if ( m[ 4 ] ) {
results = getTag( m[ 4 ], results );
} //因为标签元素选择器和通配符选择器所调用的方法一样,所以可以进行整合如下
/*if ( m[ 1 ] ) {
results = getId( m[ 1 ], results );
} else if ( m[ 2 ] ) {
results = getClass( m[ 2 ], results );
} else {
results = getTag( m[ 3 ] || "*", results )
}*/ } return results;//返回results
};
上面是用正则匹配字符串的,如果不用正则如何实现
var get = function(selector, results) {
results = results || [];
if (selector === '*') {
return results = getTag(selector, results);
} else {
var firstChar = selector.charAt(0);
switch (firstChar) {
case '.':
results = getClass(selector.slice(1), results);
break;
case '#':
results = getId(selector.slice(1), results);
break;
default:
results = getTag(selector, results);
break;
}
return results;
}
}
3、书写each方法遍历所获得的元素数组
var each = function ( arr, fn ) {
for ( var i = 0; i < arr.length; i++ ) {
if ( fn.call( arr[ i ], i, arr[ i ] ) === false ) {
break;
}
}
};
4、调用each方法,执行验证相关需求的操作
each( get( "#id" ), function () { this.style.backgroundColor = 'lightgreen';
} );
最后把以上方法整合在一起,如下
// 注释: 对基本选择器方法的封装
var getTag = function ( tag, results ) {
results = results || [];
results.push.apply( results, document.getElementsByTagName( tag ) );
return results;
}; var getId = function ( id, results ) {
results = results || [];
results.push( document.getElementById( id ) );
return results;
}; var getClass = function ( className, results ) {
results = results || []; if ( document.getElementsByClassName ) {
results.push.apply( results, document.getElementsByClassName( className ) );
} else {
each( getTag( '*' ), function ( i, v ) {
if ( ( ' ' + v.className + ' ' )
.indexOf( ' ' + className + ' ' ) != -1 ) {
results.push( v );
}
} );
}
return results;
}; // 对each方法循环的封装
var each = function ( arr, fn ) {
for ( var i = 0; i < arr.length; i++ ) {
if ( fn.call( arr[ i ], i, arr[ i ] ) === false ) {
break;
}
}
}; // 通用的get方法
var get = function ( selector, results ) {
results = results || [];
var rquickExpr = /^(?:#([\w-]+)|\.([\w-]+)|([\w]+)|(\*))$/,
m = rquickExpr.exec( selector ); if ( m ) { if ( m[ 1 ] ) {
results = getId( m[ 1 ], results );
} else if ( m[ 2 ] ) {
results = getClass( m[ 2 ], results );
} else if ( m[ 3 ] ) {
results = getTag( m[ 3 ], results );
} else if ( m[ 4 ] ) {
results = getTag( m[ 4 ], results );
} }
以上便是自己的一些学习笔记,鄙人不才,些许浅显,希望大家批评指正
关于js封装框架类库之选择器引擎(一)的更多相关文章
- 关于js封装框架类库之选择器引擎(二)
在上篇介绍了选择器的获取标签.id.类名的方法,现在我们在上篇基础上继续升级 1.问题描述:上篇get('选择器')已经实现,如果get方法里是一个选择器的父元素,父元素是DOM对象,那么如何获取元素 ...
- 关于js封装框架类库之DOM操作模块(二)
上一篇基本实现了框架结构,但是与真正能用上的项目框架比较还是存在很多不足,在这又做了些加强与优化 (function ( window, undefined ) { var arr = [], pus ...
- 关于js封装框架类库之样式操作
在js中,对样式的操作我们并不感到陌生,在很多框架中都是用极少的代码,实现更强大的功能,在这做出一些的总结.存在不足还望指出! 1.封装一个添加css的方法(这篇引用了前面的框架结构) 在 js 中 ...
- 关于js封装框架类库之DOM操作模块(一)
在前端开发的过程中,javascript极为重要的一个功能就是对DOM对象的操作,而对其封装就是为了更好地进行DOM操作,提高浏览器的支持效率 现在给出一个案例:页面创建三个div,然后给其添加样式 ...
- 关于js封装框架类库之事件模块
在触发DOM上的某个事件时,会产生一个事件对象event.这个对象中包含着所有与事件有关的信息.包括导致事件的元素,事件的类型以及其他与特定事件相关的信息. 例如: 鼠标操作点击事件时,事件对象中会获 ...
- 关于js封装框架类库之属性操作
在对DOM对象操作时,往往都要涉及到其属性的操作,为了提高开发效率,同时兼顾浏览器的性能,在这简单的封装了几个常见的属性.因为是模块化,在这只是引入了部分代码,其他代码在前几篇模块封装中有写.如有不足 ...
- 【原创】使用JS封装的一个小型游戏引擎及源码分享
1 /** * @description: 引擎的设计与实现 * @user: xiugang * @time: 2018/10/01 */ /* * V1.0: 引擎实现的基本模块思路 * 1.创建 ...
- JS框架设计读书笔记之-选择器引擎02
选择器引擎涉及相关概念 概念 以Sizzle的主函数声明为例,来说明引擎的相关概念. function Sizzle(selector, context, results, seed) { //... ...
- JS封装动画框架,网易轮播图,旋转轮播图
JS封装动画框架,网易轮播图,旋转轮播图 1. JS封装运动框架 // 多个属性运动框架 添加回调函数 function animate(obj,json,fn) { clearInterval(ob ...
随机推荐
- HTML 5 新标签
HTML 5 是一个新的网络标准,目标在于取代现有的 HTML 4.01, XHTML 1.0 and DOM Level 2 HTML 标准.它希望能够减少浏览器对于需要插件的丰富性网络应用服务( ...
- 重置出错?微软Win10平板Surface Pro 4重装系统教程详解
重置出错?微软Win10平板Surface Pro 4重装系统教程详解 2015-12-11 15:27:30来源:IT之家作者:凌空责编:凌空 评论:65 Surface Pro 4系统重置出错该怎 ...
- Android XListView实现原理讲解及分析
XListview是一个非常受欢迎的下拉刷新控件,但是已经停止维护了.之前写过一篇XListview的使用介绍,用起来非常简单,这两天放假无聊,研究了下XListview的实现原理,学到了很多,今天分 ...
- POJ 2686 Traveling by Stagecoach 壮压DP
大意是有一个人从某个城市要到另一个城市(点数<=30) 然后有n个马车票,相邻的两个城市走的话要消耗掉一个马车票. 花费的时间呢,是马车票上有个速率值,用边/速率就是花的时间. 问最后这个人花费 ...
- 《windows程序设计》学习_4:文本输出,加滚动条
//总行数 #define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0])) struct { int Index ; TCHA ...
- openNebula libvirt-virsh attach disk device for kvm
1,新建文件硬盘 qemu-img create -f qcow2 testdisk.img 2G
- append与after
apend与apendTo就如同after与insertAfter,表达意思相同,表达不同.A.after(B)=B.insertAfter(A).apend在元素里面添加,after在元素外面添加. ...
- Linux前台的程序转到后台执行(关闭终端而不杀死命令)
你是否经常遇到这样的情况,通过SSH或者终端putty连接到一台linux/unix机器,执行一个程序.一个脚本或者一条命令,但现在你需要关闭SSH或者终端,由于该该程序.脚本或者命令正在运行,一旦你 ...
- C++类的常成员函数
让一个成员函数带上常量性是什么意思呢?通常的答案是,一个常成员函数不会更改其class对象.这是一种平凡的表述,而编译器实现的手法也相当平凡. 任何非静态成员函数其实都被编译器隐式插入了一个指针类型的 ...
- mysql alter example
alter table `user_movement_log` AFTER `Regionid` (在哪个字段后面添加) ) default null; //主键 ) unsigned not nul ...