/*
* @Author: 我爱科技论坛
* @Time: 20180706
* @Desc: 实现一个类似于JQuery功能的框架

// 公共框架
// 种子模块:命名空间、对象扩展、数组化、类型的判定、domReady机制,无冲突处理
(function (xframe) {
// 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法)
xframe.extend({
each: function (fn) {
var i = 0,
len = this.length;
for (; i < len; i++) {
// call第一个参数传递的实际上就是this的执行,后面的参数就是目标函数fn需要传递的参数(可省略)
// this[i] 里面的取值方式类似于json取值,每一个参数存储了选择器获取的所有的nodeList元素集合中的一个元素
fn.call(this[i]);
}
return this;
}
}); // 不需要参与链式访问的
/*公共部分*/
xframe.extend(xframe, {}); /*字符串处理模块*/
xframe.extend(xframe, {
/*
* 下面的这几个都会用到正则表达式,会在后面补充
* camelCase函数的功能就是将形如background-color转化为驼峰表示法:backgroundColor
* */
camelCase: function (str) {
// all: -c, letter: c
return str.replace(/\-(\w)/g, function (all, letter) {
// 把所有的字母都转换为大写的状态
return letter.toUpperCase();
});
},
/**
* 去掉左边的空格 str = ' ()'
* @param str
* @returns {*}
*/
ltrim: function (str) {
/*
^ :表示以XX开头
\s: 表示空格
*: 表示匹配零个或者多个
g: 表示匹配全部,如果没有的话默认只会匹配一个
(^\s*): 表示以空格开头的一个或者多个字符
str.replace(, ''): 替换…… ----------------------------------------------------[其他用法归纳]-------------------------------------
^, $: 匹配字符串开始,结束的位置 eg:
g, i:匹配所有,不区分大小写的字符串; eg: /a/g, /a/i
*, +, ?: 匹配任意次数, 匹配前面的字符一次或者多次, 0次或者1次 [] : 匹配一个字符集合; eg: [a-z]所有小写字母的集合, [0-9]所有数字的集合
eg: [a-zA-Z]所有大小写字母的集合
脱字符^: 匹配任何不在该集合中的字符,与上面的用法正好相反
{}: 指定重复前面的一个字符多少遍 eg:{N} 重复n遍
eg:{n, m}重复n-m遍
eg: {n, }至少重复n遍
eg:{,m}至多重复m遍 // 【熟记:同类记忆法】
\s: 表示空格:包括空格、换行、回车、tab,等价于[\n\r\t\f]
\S: 匹配非空格字符,等价于[^ \n\r\t\f]
\d: 表示十进制数字,等价于[0-9]
\D: 匹配一个非数字字符, 等价于[^0-9]
\w(小写): 表示字母或者数字,等价于[a-zA-Z0-9]
\W: 非字母且非数字,与\w相反,等价于:[^a-zA-Z0-9]* * */
return str.replace(/(^\s*)/g, '');
},
/* 去掉右边的空格, str = '() '
* @param str
*/
rtrim: function (str) {
return str.replace(/(\s*$)/g, '');
},
/**
* 用于去掉两边的空格(去掉所有的空格) str =' () '
* @param str
* @returns {*}
*/
trimOld: function (str) {
return str.replace(/(\s*$)/g, '');
},
/**
* 【使用模板来实现一个简单的数据绑定】
* 实现简单的数据绑定: @(name), @(sex)
* data: var user = {name : 'xiugang', role, '钻石会员'}
* str: = '欢迎@(name), 等级:@(role)光临本站!';
* @param str 原始的数据格式
* @param data 需要绑定的数据对象,是一个json格式的数据, json = {name : 'xiuxiu', age : 18}
* @returns {*}
*/
formateString: function (str, data) {
// 使用后面的值去替换掉前面的值
// 细节分析:((\w+))使用括号匹配的值在JavaScript中实际上就是一个$1, 把这个参数传给match
// (\w+) 第二个括号实际上匹配到的就是一个$2, 把这个参数传给key
// match: @(name), @(age), @(sex)
// key: name, age, sex
return str.replace(/@\((\w+)\)/g, function (match, key) {
// 先判断有没有匹配到相应的字符串
// 找到@()开始的字符串, 使用数据域中的数据去替换
// 如果json数据data里面么有找到相应的data[key]数据,返回的实际上就是一个空的字符串
return typeof data[key] === 'undefined' ? '' : data[key];
}); },
/**
* @param str
* @returns {*}
*/
trimLeft: function (str) {
return str.replace(/^\s*/g, '');
},
/**
* @param str
* @returns {*}
*/
trimRight: function (str) {
return str.replace(/\s*$/g, '');
},
/**
* 去掉所有的空格(两边的空格), 可以针对任意格式的字符串
* 先去掉左边的空格,然后去掉右边的空格
* @param str
* @returns {*}
*/
trim: function (str) {
// var regx = '/^\s*\s*$/g';
// return str.replace(regx, '');
// | 表示或的意思, 也就是满足| 左边的也成立, 满足 | 右面的也成立
// (^\s*) 表示的就是以0个空格或者多个空格开头
// (\s*$) 的意思就是, 以0个空格或者多个空格结尾
// /…/g 是正则表达式的属性, 表示全文匹配, 而不是找到一个就停止
return str.replace(/(^\s*)|(\s*$)/g, "");
//return this.trimRight(this.trimLeft(str));
},
/**
* 发送一个ajax请求
* @param url 请求的URL地址信息
* @param fn, 请求成功的回调函数
*/
ajax: function (url, fn) {
// 创建一个XMLHTTPRequest对象
var xhr = createXHR();
// 每当 readyState 改变时,就会触发 onreadystatechange 事件。
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
// 接受到响应之后,第一步检查status属性,为200则表明成功,此时responseText已经准备就绪;
// 为304表明请求资源未被修改,可以直接使用浏览器中的缓存版本。
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
fn(xhr.responseText);
} else {
alert('错误的文件!');
}
}
}; // 定义请求参数, 对于指定的url发送一个get请求
xhr.open('get', url, true);
// 发送请求
// 第三个参数:指示请求使用应该异步地执行。
// 如果这个参数是 false,请求是同步的,后续对 send() 的调用将阻塞,直到响应完全接收。
// 如果这个参数是 true 或省略,请求是异步的,且通常需要一个 onreadystatechange 事件句柄。
xhr.send(); /**
* 创建一个XHR
*/
function createXHR() {
//本函数来自于《JavaScript高级程序设计 第3版》第21章
if (typeof XMLHttpRequest != "undefined") {
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined") {
// arguments.callee用于指向他的回调函数
if (typeof arguments.callee.activeXString != "string") {
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"
],
i, len; for (i = 0, len = versions.length; i < len; i++) {
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex) {
//skip
}
}
} return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR object available.");
}
} },
/**
* json转换为字符串
* @param json
* @returns {string}
*/
json2String: function (json) {
return JSON.stringify(json);
},
/**
* 字符串转换为json
* @param str
* @returns {any}
*/
string2Json: function (str) {
return eval(str);
}
}); /*数组相关*/
xframe.extend(xframe, {
/**
* 将一个数组清空,并返回数组的引用
* 只需要把数组的元素置空为0即可
* @return {xframe}
*/
clear: function () {
this.length = 0;
return this; },
/**
* 返回数组的第0个元素
* @return {*}
*/
first: function () {
return this[0]; },
/**
* 返回数组的最后一个元素
* @return {*}
*/
last: function () {
return this[this.length - 1];
},
/**
* 计算一个数组的大小尺寸
* @return {number|*}
*/
size: function () {
return this.length;
},
cacl: function (arr, callback) {
var ret;
for (var i = 0; i < arr.length; i++) {
// 专门用于处理每一项的计算机过程
ret = callback(arr[i], ret);
}
return ret;
},
/**
* 对数组里面的所有元素求和
* @return {*}
*/
sum: function () {
// 1. 正常写法
var ret;
for (var i = 0; i < this.length; i++) {
ret = ret + this[i];
}
return ret;
},
max: function () { },
min: function () { },
avg: function () { },
intersect: function () { },
union: function () { },
diff: function () { },
unique: function () { },
forEach: function () { },
map: function () { },
filter: function () { },
every: function () { },
some: function () { },
reduce: function () { },
reduceRight: function () { },
indexOf: function () { },
lastIndexOf: function () { },
enhanceUnique: function () { },
without: function () { },
flatten: function () { },
random: function () { },
removeAt: function () { },
contains: function () { }
}); /*Math*/
xframe.extend(xframe, {
random: function () { } }); /*数据类型检验*/
xframe.extend(xframe, {
// 鸭子类型(duck typing)如果它走起路来像鸭子,叫起来也是鸭子,那么它就是鸭子。
// 只关注对象的行为,不关注对象本身面向接口编型 ,而不是面向实现编程,是设计模式中最重要的思想。
// 【理解】:一个对象有效的语义,不是由集成自特定的类或实现特定的接口, 而是由当前方法和属性的集合决定的!!!
isNumber: function (val) {
// 如果这个数字是有限的话, 而且是数字类型
return (typeof val === 'number' && isFinite(val)) && (Object.prototype.toString.call(val) === '[object Number]');
},
/***
* 判断一个变量是不是Boolean类型
* @param val
* @returns {boolean}
*/
isBoolean: function (val) {
return (typeof val === 'boolean') && (Object.prototype.toString.call(val) === '[object Boolean]');
},
/**
* 判断一个变量是不是字符串类型
* @param val
* @returns {boolean}
*/
isString: function (val) {
return (typeof val === 'string') && (Object.prototype.toString.call(val) === '[object String]');
},
/**
* 判断一个变量是不是undefined
* @param val
* @returns {boolean}
*/
isUndefined: function (val) {
// oid 0 is a correct and standard way to produce undefined.
return (val === void 0) || (typeof val === 'undefined') && (Object.prototype.toString.call(val) === '[object Undefined]');
},
/**
* 判断一个变量是不是为空
* @param val
* @returns {boolean}
*/
isNull: function (val) {
return (val === null) && (Object.prototype.toString.call(val) === '[object Null]');
},
/**
* 检测
* @param obj
* @returns {*}
*/
isNaN: function (val) {
// 只要这个数字通过判断是不是和他自身相同或者使用typef的方式去检测
return val !== val;
},
/**
* 判断一个变量是不是一个对象类型
* @param val
* @returns {boolean}
*/
isObject: function (val) {
if (val !== null && val !== undefined) {
if ((typeof val === 'object') && (Object.prototype.toString.call(val))) {
return true;
}
}
return false;
},
/**
* 判断一个对象是不是数组对象
* @param val
* @returns {boolean|void|string}
*/
isArray: function (val) {
// 判断上不是一个数组的先判断这个数组对象是不是为空, 因为如果val为空的话,就是val.constructor这个属性实际上是没有的,error
if (val !== null || typeof val !== "undefined") {
// 注意在使用constructor判断数据类型的时候比较的实际上是他的原型对象的constructor属性, 这个属性指向的实际上是这个变量的原型对象
return (val.constructor === Array) && (Object.prototype.toString.call(val));
}
return false;
} }); /*数组化:arguments, document.forms, document.getElementsByName, document.getElementsByTagName()*/
xframe.extend(xframe, {
/**
* 把一个伪数组转换为一个新的数组
* 实现思路: 取出伪数组中的每一个元素, 然后把取出来的这些元素重新放入到一个新的数组里面去!!!
* @param start
* @param end
* @returns {Array}
*/
toArray: function (start, end) {
var result = [];
var start = start || 0,
// 这里的this指向调用的对象,使用了call之后, 改变了this的指向, 指向传进来的对象(外边必须要修改this的指向)
// 如果外边不修改this的指向,这里的this默认指向的是xframe这个框架对象
end = end || this.length;
for (var i = start; i < end; i++) {
result.push(this[i]);
}
return result;
}, /**
* 方法二: 直接把一个伪数组转换为JavaScript中的一个数组对象
* @param obj
* @returns {T[]}
*/
slice: function (obj) {
return Array.prototype.slice.apply(obj);
}
}); /*domReady的实现*/
xframe.extend(xframe, {
//arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数
/**
* 实现一个domReady方法:所有元素都加载完毕之后一个回调函数
* @param domElement
* @param fn
*/
onDOMReady: function (fn) {
if (document.addEventListener) {
// W3C组织: 如果传过来的是一个DOM元素的话,就直接对这个DOM元素添加监听, 否则,就对整个document添加事件监听
document.addEventListener('DOMContentLoaded', fn, false);
} else {
// IE浏览器
IEContentLoaded(fn);
} /**
* 微软的IE浏览器的处理方法
* @param fn
* @constructor
*/
function IEContentLoaded(fn) {
// 定义需要的全局变量
var done = false, document = window.document; // 这个函数只会在所有的DOM节点树创建完毕的时候才会继续向下执行
var init = (function () {
if (!done) {
console.log('done……');
// 如果DOM树创建完毕的话
done = true;
fn();
}
})(); /*
使用这个立即函数来调用IE浏览器的内置函数实现domReady的功能
*/
(function () {
try {
// DOM树在未创建完毕之后调用 doScroll的话,会抛出错误
document.documentElement.doScroll('left'); } catch (err) {
// 延迟1秒之后再次执行这个函数, 形成一个函数递归调用的功能【回调函数】
// clllee是一个函数指针,指向的是拥有这个arguments对象的函数, 从而实现再次调用这个函数
setTimeout(arguments.callee, 1);
return;
} // 如果没有错误的话,表示DOM树已经完全创建完毕, 此时开始执行用户的回调函数
init();
})(); // 监听document的加载状态(DOM加载的过程中会不断回调这个函数)
document.onreadystatechange = function () {
console.log('onreadystatechange……');
if (document.readyState === 'complete') {
console.log('complete……');
// 如果加载完成的话
document.onreadystatechange = null;
init();
}
}
}
}
});
})(xframe);

【JavaScript框架封装】公共框架的封装的更多相关文章

  1. 【JavaScript框架封装】自己动手封装一个涵盖JQuery基本功能的框架及核心源码分享(单文件版本)

    整个封装过程及阅读JQuery源码的过程基本上持续了一个月吧,最终实现了一个大概30%的JQuery功能的框架版本,但是里面涉及的知识点也是非常多的,总共的代码加上相关的注释大概在3000行左右吧,但 ...

  2. Thinkphp3.2.3框架下封装公共的函数,例如封装CURL函数来获取接口数据

    当我们需要在控制层调用相同的封装函数时,写多次相同的函数,显得代码十分的拉杂,不精简: TP框架有一个很好的机制,可以再Common定义一个function.php函数,当我们在控制层调用的时候直接调 ...

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

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

  4. 封装Ajax框架!(前言篇)

    Ajax技术就是利用javascript和xml实现异步交互的功能. 首先先来介绍一下Ajax相关知识点,如果这些你都会的话,请直接跳转到封装ajax框架!(代码篇) 一.Ajax对象的创建 1.创建 ...

  5. JS封装动画框架,网易轮播图,旋转轮播图

    JS封装动画框架,网易轮播图,旋转轮播图 1. JS封装运动框架 // 多个属性运动框架 添加回调函数 function animate(obj,json,fn) { clearInterval(ob ...

  6. 封装Ajax框架!(代码篇)

    写在前面的话,如果中间有什么不明白的,请先看封装ajax框架!(前言篇) 1.添写一个封闭函数 (function(){})(); 在一个项目中,可能会引用多个js框架,如果函数名相同,会有命名冲突, ...

  7. 第61天:json遍历和封装运动框架(多个属性)

    一.json 遍历  for in  关键字  for ( 变量 in  对象)  { 执行语句;  } 例如: var json = {width:200,height:300,left:50}co ...

  8. 转: javascript模块加载框架seajs详解

    javascript模块加载框架seajs详解 SeaJS是一个遵循commonJS规范的javascript模块加载框架,可以实现javascript的模块化开发和模块化加载(模块可按需加载或全部加 ...

  9. javascript模块加载框架seajs详解

    SeaJS是一个遵循commonJS规范的javascript模块加载框架,可以实现javascript的模块化开发和模块化加载(模块可按需加载或全部加载).SeaJS可以和jQuery完美集成,使用 ...

随机推荐

  1. SQL Server 2008 复制到MySQL

    SQLServer2008正在配放订阅的时候是能够看到收撑订阅办事器为Oracle或者DB2的,可是复制到MySQL没无间接的界面操做. 颠末测试,通过MySQL的ODBC驱动,是能够实现将SQLSe ...

  2. fzu 2173 floyd+矩阵快速幂

    #include<stdio.h> #define inf 1000000000000000 #define N 100 long long tmp[N][N],ma[N][N]; int ...

  3. LightOJ - 1231 - Coin Change (I)

    先上题目: 1231 - Coin Change (I)   PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit:  ...

  4. 模型概念--MVC-MVVM

    MVVM 第一个M是数据访问曾,第二个v是view视图页面,第三个vm是ViewModel视图模型

  5. python中经常使用的字典内建函数

    1.len(mapping)        返回映射的长度(键-值对的个数) 2.hash(obj)              返回obj的哈希值 >>> myDict = {'na ...

  6. 【JavaScript】——JS入门

    结束XML之旅,開始JavaScript的学习,看视频.了解了她的前世今生,还是为她捏了把汗啊! 看了部分视 频了,简单的总结一下吧! JavaScript是什么? JavaScript是一种基于面向 ...

  7. bzoj2958: 序列染色(DP)

    2958: 序列染色 题目:传送门 题解: 大难题啊(还是我太菜了) %一发大佬QTT 代码: #include<cstdio> #include<cstring> #incl ...

  8. spark rdd median 中位数求解

    lookup(key) Return the list of values in the RDD for key key. This operation is done efficiently if ...

  9. linux IPtable防火墙 禁止和开放端口(转)

    linux IPtable防火墙 禁止和开放端口源:http://hi.baidu.com/zplllm/item/f910cb26b621db57c38d5983评: 1.关闭所有的 INPUT F ...

  10. getElementById和querySelector区别

    1.常见的获取元素的方法有3种,分别是通过元素ID document.getElementById('idName');.通过标签名字document.getElementsByTagName(tag ...