// 选择框架
(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的选择框架的封装的更多相关文章

  1. 【JavaScript框架封装】实现一个类似于JQuery的基础框架、事件框架、CSS框架、属性框架、内容框架、动画框架整体架构的搭建

    /* * @Author: 我爱科技论坛 * @Time: 20180715 * @Desc: 实现一个类似于JQuery功能的框架 * V 1.0: 实现了基础框架.事件框架.CSS框架.属性框架. ...

  2. 分析一个类似于jquery的小框架

    在网上下了一个类似于jQuery的小框架,分析源码,看看怎么写框架. 选择器Select //用沙箱闭包其整个代码,只有itcast和I暴漏在全局作用域 (function( window , und ...

  3. 【JavaScript框架封装】实现一个类似于JQuery的DOM框架的封装

    // DOM框架(选择器框架) (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 向现 ...

  4. 【JavaScript框架封装】实现一个类似于JQuery的缓存框架的封装

    // 缓存框架 (function (xframe) { /** * 实现了缓存框架的临时存储功能(内存存储) * @type {{data: Array, get: (function(*): *) ...

  5. 【JavaScript框架封装】实现一个类似于JQuery的动画框架的封装

    // 动画框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({}); // 不需要参与链式访问的 ...

  6. 【JavaScript框架封装】实现一个类似于JQuery的属性框架的封装

    // 属性框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 获取/设置某一个元素 ...

  7. 【JavaScript框架封装】实现一个类似于JQuery的事件框架的封装

    // 事件框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 实现一个浏览器的基本 ...

  8. 【JavaScript框架封装】实现一个类似于JQuery的内容框架的封装

    // 内容框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * .html()用为读 ...

  9. 分析一个类似于jquery的小框架 (2)

    核心构造函数 (function ( window, undefined ) { // 定义Itcast构造函数 function Itcast ( selector ) { return new I ...

随机推荐

  1. MySQL主要命令(4)

    显示数据, 给列区别名: select coL_name as 别名     from table_name;

  2. asp.net控件的异步刷新

    需求:我们知道,asp.net控件中的button控件,默认是开启了自己主动回发的,而有时候.我们不想刷新整个界面.而仅仅想局部刷新,可页面中又偏偏用到了.net button控件. 尽管我非常讨厌. ...

  3. 单片机project师必备的知识

    C语言编程 程序编译过程  哪部分干什么 数据结构  链表 二叉树 算法   数组  堆栈 队列算法 遍历 常量在内存中的表现形式 语法和内存的相应关系 数电 UML 类图 时序图 状态图 用例图   ...

  4. 《linux 内核全然剖析》 笔记 CODE_SPACE 宏定义分析

    在memory.c里面.遇到一个宏定义,例如以下: #define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \ current->sta ...

  5. Windows下搭建ffmpeg+VS2008开发环境详细教程【转】

    本文转载自:http://www.voidcn.com/article/p-vxdntdgc-bkq.html 由于个人是从事音视频开发相关的工作,所以也把自己的一些过程写下来,方便大家以及自己查看, ...

  6. [HTML5] 新标签解释及用法

    转自:http://www.cnblogs.com/yuzhongwusan/archive/2011/11/17/2252208.html HTML 5 是一个新的网络标准,目标在于取代现有的 HT ...

  7. hihoCoder-1828 2018亚洲区预选赛北京赛站网络赛 A.Saving Tang Monk II BFS

    题面 题意:N*M的网格图里,有起点S,终点T,然后有'.'表示一般房间,'#'表示毒气房间,进入毒气房间要消耗一个氧气瓶,而且要多停留一分钟,'B'表示放氧气瓶的房间,每次进入可以获得一个氧气瓶,最 ...

  8. 解决PopupWindow的阴影覆盖问题

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/108 PopupWindow阴影覆盖问题 最近这段时间需求 ...

  9. Pop3协议详解

      POP3全称为Post Office Protocol version3,即邮局协议第3版.它被用户代理用来邮件服务器取得邮件.POP3采用的也是C/S通信 模型 用户从邮件服务器上接收邮件的典型 ...

  10. B - Beautiful Year

    Problem description It seems like the year of 2013 came only yesterday. Do you know a curious fact? ...