【JavaScript框架封装】实现一个类似于JQuery的选择框架的封装
// 选择框架
(function (xframe) {
// 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法)
xframe.extend({});
// 不需要参与链式访问的
xframe.extend(xframe, {
/**
* ID选择器
* @param context
* @return {HTMLElement | *}
*/
$id: function (context) {
// context是一个DOM对象还是字符串
context = this.isString(context) ? document.getElementById(context) : context;
return context;
},
/**
* tag选择器, context;里面存储了上下文信息(尽量少的使用局部变量)
* @param tag
* @param context
* @return {NodeListOf<HTMLElementTagNameMap[keyof HTMLElementTagNameMap]>}
*/
$tag: function (tag, context) {
// 分为两种情况
if (typeof context === 'string') {
context = this.$id(context);
}
// 按照这种思路,只有可能是一种情况
if (context) {
if (context.length) {
// 这里默认只会返回数组中的第0个元素
return [].slice.call(context)[0].getElementsByTagName(tag);
} else {
return context.getElementsByTagName(tag);
}
}
return document.getElementsByTagName(tag);
},
/**
* 实现一个类选择器
* @param className
* @param context
* @return {*}
*/
$class: function (className, context) {
// context里面此时存储的是一个DOM节点元素
// 如果直接传过来的是一个DOM元素节点context(DOM元素的话就单独处理)
context = this.$id(context) || document;
// 1.由于getElementByClassName()这个方法是不兼容的,因此需要使用浏览器内置的方法去获取类选择器
// 2. 可以使用getElementByTagName()的方法去获取所有的标签元素,然后把再使用className的属性间接去实现一个类似的class选择器的功能
if (context.getElementsByClassName) {
// 如果支持这个方法的话
return context.getElementsByClassName(className);
} else {
// 不支持的话就间接获取
var doms = context.getElementsByTagName('*'),
res = [];
// 使用自己定义的方法去实现一个类选择器
doms.each(function () {
if (this.className === className) {
// 只要是找到了这个class的集合,就放入到一个数组里面
res.push(this);
}
});
return res;
}
},
/**
* 使用管道思想实现一个层次选择器
* @return {Array}
*/
$cengci: function () {
var self = this;
// 主要功能:实现一个层次选择器
// 输入字符串: str = '#className div a p' 选择所有的className 下面的P标签
// 1. 获取穿过来的参数(数组元素去重)
var args = Array.prototype.slice.call(arguments)[0].toString().split(' '),
index,
first,
item,
selector,
res = [], // 存储了本次的结果信息
context = []; // 存储了上一次的上下文信息【管道思想!】, context = 'tag .class #id'
// 思考: 为了实现一个层次选择器, 如何实现一个吧上一次选择的元素全部存储起来???
// 2. 开始解析参数信息
args.each(function () {
// 每次重复之前,先把本次需要存储的数组清空(res里面存储了每次的最新数据)
res = [];
// 对获取到的每一项进行处理
item = this.trim();
first = item.charAt(0);
index = item.indexOf(first);
selector = item.slice(index + 1);
// 使用管道思想实现一个层次选择器!!!
switch (first) {
case '.': // class 选择器
if (context.length) {
// 说明这一次的class类选择器中的元素不是第一次出现
context.each(function () {
pushArray(self.$class(selector, this));
});
} else {
// 如果是第一次出现的话
pushArray(self.$class(selector));
}
// 把上一次执行的结果存起来
context = res;
break;
case '#': // ID选择器
// 由于ID选择器获取的元素始终是唯一的,因此直接放进去即可
res.push(self.$id(selector));
// 把上一次执行的结果存起来
context = res;
break;
default: // tag选择器
if (context.length) {
// 说明不是第一次出现
context.each(function () {
// 注意在使用tag选择器的时候,第二个参数必须是一个ID选择器,或者是一个
// 1. 注意在放入数组的时候,需要逐个遍历然后放进去
pushArray(self.$tag(item, this));
});
} else {
// 第一次出现的
pushArray(self.$tag(item));
}
// 把上一次执行的结果存起来
context = res;
break;
}
});
/**
* 把公共的部分代码封装起来
* @param doms
*/
function pushArray(doms) {
if (doms) {
[].slice.call(doms).each(function () {
res.push(this);
});
}
}
return context;
},
/**
* group选择器
* @return {Array}
*/
$group: function () {
var self = this;
// '.moshou,#moshou,span,.dream'
// 1. 获取传过来的参数
var args = [].slice.call(arguments),
arr = args[0].split(',').unique(), // 这里在拿到这个分割后的字符串后,开始进行数组元素去重
item,
index,
first,
selector;
res = [];
// 2. 开始遍历参数集合,解析参数信息
arr.each(function () {
// 3. 开始遍历得到结果,获取每一项
item = this.trim();
// 4. 开始获取首字母信息,和后面的选择器信息
// 4. 获取指定下标位置对应的字符
first = item.charAt(0);
index = item.indexOf(first);
selector = item.slice(index + 1);
// 开始根据第一个字母向下进行判断,把满足相应条件的放在数组里面
switch (first) {
case '.':
// class选择器
res.push(self.$class(selector));
break;
case '#':
// ID 选择器
res.push(self.$id(selector));
break;
default:
// TAG选择器(直接就是first本身,这里不用再判断了使用selector这个变量了)
res.push(self.$tag(item));
break;
}
});
return res;
},
/**
* 多组+层次选择器
* @return {Array}
*/
$select: function () {
// str = '#tag , .calss'
var args = [].slice.call(arguments)[0].toString().split(','),
ret = [],
self = this;
// 遍历args数组,对数组的每一项采用层次选择器
args.each(function () {
// 1. 对于逗号分隔的部分采用层次选择,获取层次选择器的结果信息, 是一个数组集合
var res = self.$cengci(this);
// 2. 遍历层次选择器的集合,把信息放入到一个新的数组里面, 就是得到的多组选择器的结果信息
pushArray(res);
});
// 层次选择器
function pushArray(doms) {
if (doms.length) {
doms.each(function () {
ret.push(this);
});
}
}
return ret;
}
});
})(xframe);
【JavaScript框架封装】实现一个类似于JQuery的选择框架的封装的更多相关文章
- 【JavaScript框架封装】实现一个类似于JQuery的基础框架、事件框架、CSS框架、属性框架、内容框架、动画框架整体架构的搭建
/* * @Author: 我爱科技论坛 * @Time: 20180715 * @Desc: 实现一个类似于JQuery功能的框架 * V 1.0: 实现了基础框架.事件框架.CSS框架.属性框架. ...
- 分析一个类似于jquery的小框架
在网上下了一个类似于jQuery的小框架,分析源码,看看怎么写框架. 选择器Select //用沙箱闭包其整个代码,只有itcast和I暴漏在全局作用域 (function( window , und ...
- 【JavaScript框架封装】实现一个类似于JQuery的DOM框架的封装
// DOM框架(选择器框架) (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 向现 ...
- 【JavaScript框架封装】实现一个类似于JQuery的缓存框架的封装
// 缓存框架 (function (xframe) { /** * 实现了缓存框架的临时存储功能(内存存储) * @type {{data: Array, get: (function(*): *) ...
- 【JavaScript框架封装】实现一个类似于JQuery的动画框架的封装
// 动画框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({}); // 不需要参与链式访问的 ...
- 【JavaScript框架封装】实现一个类似于JQuery的属性框架的封装
// 属性框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 获取/设置某一个元素 ...
- 【JavaScript框架封装】实现一个类似于JQuery的事件框架的封装
// 事件框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 实现一个浏览器的基本 ...
- 【JavaScript框架封装】实现一个类似于JQuery的内容框架的封装
// 内容框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * .html()用为读 ...
- 分析一个类似于jquery的小框架 (2)
核心构造函数 (function ( window, undefined ) { // 定义Itcast构造函数 function Itcast ( selector ) { return new I ...
随机推荐
- MySQL主要命令(4)
显示数据, 给列区别名: select coL_name as 别名 from table_name;
- asp.net控件的异步刷新
需求:我们知道,asp.net控件中的button控件,默认是开启了自己主动回发的,而有时候.我们不想刷新整个界面.而仅仅想局部刷新,可页面中又偏偏用到了.net button控件. 尽管我非常讨厌. ...
- 单片机project师必备的知识
C语言编程 程序编译过程 哪部分干什么 数据结构 链表 二叉树 算法 数组 堆栈 队列算法 遍历 常量在内存中的表现形式 语法和内存的相应关系 数电 UML 类图 时序图 状态图 用例图 ...
- 《linux 内核全然剖析》 笔记 CODE_SPACE 宏定义分析
在memory.c里面.遇到一个宏定义,例如以下: #define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \ current->sta ...
- Windows下搭建ffmpeg+VS2008开发环境详细教程【转】
本文转载自:http://www.voidcn.com/article/p-vxdntdgc-bkq.html 由于个人是从事音视频开发相关的工作,所以也把自己的一些过程写下来,方便大家以及自己查看, ...
- [HTML5] 新标签解释及用法
转自:http://www.cnblogs.com/yuzhongwusan/archive/2011/11/17/2252208.html HTML 5 是一个新的网络标准,目标在于取代现有的 HT ...
- hihoCoder-1828 2018亚洲区预选赛北京赛站网络赛 A.Saving Tang Monk II BFS
题面 题意:N*M的网格图里,有起点S,终点T,然后有'.'表示一般房间,'#'表示毒气房间,进入毒气房间要消耗一个氧气瓶,而且要多停留一分钟,'B'表示放氧气瓶的房间,每次进入可以获得一个氧气瓶,最 ...
- 解决PopupWindow的阴影覆盖问题
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/108 PopupWindow阴影覆盖问题 最近这段时间需求 ...
- Pop3协议详解
POP3全称为Post Office Protocol version3,即邮局协议第3版.它被用户代理用来邮件服务器取得邮件.POP3采用的也是C/S通信 模型 用户从邮件服务器上接收邮件的典型 ...
- B - Beautiful Year
Problem description It seems like the year of 2013 came only yesterday. Do you know a curious fact? ...