【JavaScript框架封装】公共框架的封装
/* * @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);

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
【JavaScript框架封装】使用Prototype给Array,String,Function对象的方法扩充
版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81055991 /* * @Author: 我爱科技论坛 * @Time: 20180705 * @Desc: 实现一个类似于JQuery功能的框架 * V 1.0: 实现了基础框架、事件框架、CSS框架、属性框架、内容框架、动画框架的搭建 * V 2.0:实现了框架的进一步优化,具有良好的扩展性, 可以支持链式访问 * V 3.0:种子模块:命名空间、对象扩展、数组化、类型的判定、domReady,无冲突处理 * V 4.0: 数据类型的检测、正则表达式的基本用法,数据绑定的知识(模板的使用) * */ /** * 用于给js中内置的对象进行扩充方法 */ (function () { // 为了使得下面定义的扩充函数执行,祥和里需要调用一下 stringExtend() arrayExtend() functionExtend() // String对象方法的扩充 f...
- 下一篇
C++复合类型总结(指针)
引用是变量的别名,指针就是变量地址的别名。 与引用类似,指针也实现了对其他对象的间接访问。然而指针与引用又有很多不同点: 指针本身是一个对象,允许对指针赋值和拷贝。而且在指针的声明周期内它可以先后指向几个不同的对象。 指针无须在定义时赋初始值。(不太建议这个做法)和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。 一、基本操作 1. 初始化 建议初始化所有指针。 使用未经初始化的指针是引发运行时错误的一大原因。和其他变量一样,访问未经初始化的指针所引发的后果也是无法预计的。通常这一行为将造成程序崩溃,而且一旦崩溃,要想定位到出错位置将是特别棘手的问题。 在大多数编译器环境下,如果使用了未经初始化的指针,则改指针所占内存空间的当前内容将被看作一个地址值。访问该指针,相当于去访问一个本不存在的位置上的本不存在的对象。糟糕的是,如果指针所占内存空间恰好有内容,而这些内容又被当做了某个地址,我们就很难分清它到底是合法的还是非法的了。 因此建议初始化所有的指针,并且在可能的情况下,尽量等定义了对象之后再定义指向它的指针。 如果是实在不清楚指针应该指向何处,就把它...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Windows10,CentOS7,CentOS8安装Nodejs环境
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,8上快速安装Gitea,搭建Git服务器
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2全家桶,快速入门学习开发网站教程