【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 ...
随机推荐
- ISAP 算法的学习
http://www.renfei.org/blog/isap.html 算法与数学 网络流-最大流问题 ISAP 算法解释 2013-08-07Renfei Song 2 条评论 内容提要 [隐藏] ...
- Java经典线程同步问题------生产者与消费者
先上代码 class Test { public static void main(String []args) { Queue q=new Queue(); Producer p=new Produ ...
- 面向基于英特尔® 架构的 Android* 的 CoCos2D
Cocos2D 是一款游戏引擎,可与从电脑到手机等多种设备配合使用. 该引擎支持丰富的特性,可帮助创建出色的 2D 游戏.它甚至包含具备全面功能的物理引擎. CoCos2D 的核心元素是基本动画元素( ...
- C#调用C++回调函数的问题
C++的回调函数中有一个参数是,是返回一个字符串,原则如下: typedef void (*TDataEvent)(char *AData ,int ALen); 其中char ...
- gcc 4.8安装
suse的安装参考:http://blog.csdn.net/cloudskyfhx/article/details/17660607 有些错误处理见本文黄色部分 CentOS 6.4 编译安装 gc ...
- LightOJ--1149--Factors and Multiples(二分图好题)
Factors and Multiples Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu ...
- 【转】坑爹的AsyncTask之根本停不下来
原文网址:http://www.jianshu.com/p/0c6f4b6ed558 上篇<坑爹的AsyncTask之内存泄露>已经简单的探讨过线程使用不当会造成内存泄露的问题,在Acti ...
- 如何用ajax写分页查询(以留言信息为例)-----2017-05-17
要写分页,首先你得清楚,一页你想显示多少条信息?如何计算总共显示的页数? 先说一下思路: (1)从数据库读取数据,以chenai表为例,读取所有留言信息.并能够实现输入发送者,可以查询该发送者的留言总 ...
- 关于Html基础语法学习
晚上做完初赛,好像有点颓,就来学了学html,毕竟博客里面会用到嘛. 首先贴出我所学习的教程 http://www.w3school.com.cn/html/index.asp 我觉得吧,可能以我的记 ...
- guice 整合ninja framework(七)
ninja是一个优秀的,轻量级的mvc框架,它与google guice整合比较好.下面看一下例子: 我们在web.xml 配置一下: <listener> <listener-cl ...