zoukankan      html  css  js  c++  java
  • 【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,等价于[
    
    	f]
                S: 匹配非空格字符,等价于[^ 
    
    	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);
    

  • 相关阅读:
    BestCoder6 1002 Goffi and Squary Partition(hdu 4982) 解题报告
    codeforces 31C Schedule 解题报告
    codeforces 462C Appleman and Toastman 解题报告
    codeforces 460C. Present 解题报告
    BestCoder3 1002 BestCoder Sequence(hdu 4908) 解题报告
    BestCoder3 1001 Task schedule(hdu 4907) 解题报告
    poj 1195 Mobile phones 解题报告
    二维树状数组 探索进行中
    codeforces 460B Little Dima and Equation 解题报告
    通过Sql语句控制SQLite数据库增删改查
  • 原文地址:https://www.cnblogs.com/52tech/p/9338796.html
Copyright © 2011-2022 走看看