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);
    

  • 相关阅读:
    Dijjer:给流媒体插上 P2P 的同党
    gnomecolorchooser:桌面颜色设置小对象
    LXPanel:轻巧疾速的桌面面板
    批量创立缩略图
    SPE IDE:跨平台的 Python IDE
    主管的信
    使用 TRegistry 类[2]: 读取 IE 浏览器的 Start Page
    用多媒体库 Bass.dll 播放 mp3 [15] 设置与获取播放速度
    用多媒体库 Bass.dll 播放 mp3 [14] 频率均衡器
    用多媒体库 Bass.dll 播放 mp3 [13] 混响(Reverb)效果
  • 原文地址:https://www.cnblogs.com/52tech/p/9338796.html
Copyright © 2011-2022 走看看