JS常用方法封装

做项目是遇到一个封装的不错的Util类,写一下,长期备用:

CMD标准

define(function(require, exports, module) {
    "use strict";

    function Util() {}

    (function() {
        Util.isWindow = function(obj) {
            return obj !== null && obj === obj.window;
        };

        Util.isFunction = function(obj) {
            return typeof obj === 'function';
        };

        Util.isObject = function(obj) {
            return typeof obj === 'object';
        };

        Util.isArray = function(obj) {
            return obj instanceof Array;
        };

        Util.isPlainObject = function(obj) {
            return Util.isObject(obj) && !Util.isWindow(obj);
        };

        Util.isString = function(obj) {
            return typeof obj === 'string';
        };

        // 将其他的object统统搞到一个object中去
        // 这个函数不如直接写两个参数看着舒服 target objects,就不用各种slice shift了
        Util.extend = function(target) {
            var deep;
            var args = [].slice.call(arguments, 1);

            if (typeof target === 'boolean') {
                deep = target;
                target = args.shift();
            }

            args.forEach(function(arg) {
               extend(target, arg, deep);
            });

            return target;

            // 这个函数就是把source里面的一层一层往下展开给target,object 和 array会一直展开
            function extend(target, source, deep) {
                for (var key in source) {
                    if (deep && (Util.isPlainObject(source[key]) || Array.isArray(source[key]))) {
                        if (Util.isPlainObject(source[key]) && !Util.isPlainObject(source[key])) {
                            target[key] = {};
                        }

                        if (Array.isArray(source[key]) && !Array.isArray(target[key])) {
                            target[key] = [];
                        }
                        extend(target[key], source[key], deep);
                    } else {
                        target[key] = source[key];
                    }
                }
            }
        };

        Util.ajaxGet = function(url, data, callback) {
            // 简单学习一下XMLHttpRequest,一个JS对象,提供了封装的获得url上资源数据的方法,支持xml http ftp file
            // 步骤简单: open(method, url, sync), send(), 如果是异步的话 就调用onreadystatechange方法
            var xhr = new XMLHttpRequest();
            // 设置超时时间为30s
            xhr.timeout = 30000;

            xhr.onreadystatechange = function() {
                console.log("xhr.status is " + xhr.readyState);
                if (xhr.readyState === 4) {
                    var status = 0;
                    try {
                        status = xhr.status;
                    } catch(e) {
                        // eat and ignore the exception, since access the status of XHR might cause a exception after timeout occurs;
                        return;
                    }

                    if (status === 200) {
                        var result = null;
                        try {
                            result  = JSON.parse(xhr.responseText.replace(/\n|\r|\t|\b|\f/g, ''));
                        } catch(e) {
                            callback(null);
                            return;
                        }
                        callback(result);
                    } else {
                        callback(null);
                    }

                    xhr.onreadystatechange = null;
                    xhr = null;
                }
            };
            xhr.withCredentials = true;
            xhr.open("GET", url + "?" + data, true);
            xhr.send(null);
            return xhr;
        };

        Util.ajaxPost = function(url, data, callback) {
            var xhr = new XMLHttpRequest();
            // 原来navigator除了online,还有个connection
            // 这个connection,而且这个connection很刁,何以拿到type,还有change事件
            // 关键是一大堆浏览器都TM的不支持
            var connection = navigator.connection;
            switch(connection.type) {
                case connection.WIFI :
                case connection.ETHERNET:
                    xhr.timeout = 3000;
                    break;
                case connection.CELL_3G:
                case connection.CELL_4G:
                    xhr.timeout = 5000;
                    break;
                case connection.CELL_2G:
                    xhr.timeout = 30000;
                    break;
                default :
                    xhr.timeout = 30000;
            }

            // POST比GET复杂,首先不同网络timeout不一样,其次有很多事件需要监听
            xhr.addEventListener("error", function(e) {
                if (e && e.loaded === 60) {
                    // https error
                    if (e.total === 9) {
                        callback("CERTIFICATE TIME ERROR");
                    } else {
                        callback("CERTIFICATE ERROR");
                    }
                } else {
                    callback("NETWORK_ERROR");
                }
            });

            xhr.addEventListener("abort", function() {
                console.log("request abort!");
            });

            xhr.addEventListener("timeout", function() {
                callback("TIMEOUT");
            });

            xhr.addEventListener("readystatechange", function() {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        var result;
                        try {
                            result = JSON.parse(xhr.responseText.replace(/\n|\r|\t|\b|\f/g, ''));
                        } catch(e) {
                            callback("DATA_INVALID");
                            return;
                        }
                        callback(result);
                    } else if (xhr.status !== 0) {
                        callback("HTTP_ERROR");
                    }
                }
            });

            // withCredentials = true 将使得请求会带上cookie
            xhr.withCredentials = true;
            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xhr.send(data);
            return xhr;
        };

        Util.abort = function(xhr) {
            xhr.abort;
        };

        Util.getGeoLocation = function(callback) {
            var timeout = 30000;
            if (navigator.connection && navigator.connection.type) {
                switch (navigator.connection.type) {
                    // wifi
                    case 2:
                        timeout = 8000;
                        break;
                    // 2G
                    case 3:
                        timeout = 30000;
                        break;
                    // 3g:
                    case 4:
                        timeout = 20000;
                        break;
                    default:
                        timeout = 30000;
                        break;
                }
            }

            // 这里就是浏览器获取地理位置的用法
            navigator.geolocation.getCurrentPosition(
                function(position) {
                callback.call(this, position);
                }.bind(this),
                function(error) {
                    callback.call(this, null);
                }.bind(this),
                {
                    enableHighAccuracy: true,
                    maximumAge: 180000,
                    timeout: timeout
                });
        };

        // 实时定位, 返回一个ID,用来取消监听
        Util.startWatchGeoLocation = function(callback) {
            return navigator.geolocation.watchPosition(
                function(position) {
                    callback.call(this, position);
                }.bind(this),
                function() {
                    callback.call(this, null);
                }.bind(this),
                {
                    maximumAge: 600000,
                    timeout: 20000
                }
            );
        };

        Util.stopWatchGeoLocation = function(geoId) {
            navigator.geolocation.clearWatch(geoId);
        };

        // 主要用来 ajax request中把object转为字符串
        Util.paramToStr = function(params) {
            var data = '';
            var isFirstChar = true;
            for (var key in params) {
                if (params.hasOwnProperty(key)) {
                    if (isFirstChar === true) {
                        isFirstChar = false;
                        data += key + "=" + params[key];
                    } else {
                        data += "&" + key + "=" + params[key];
                    }
                }
            }
            return data;
        };

        // 预加载一个Image
        Util.preloadImage = function(images) {
            if (images && images.length) {
                for(var i = 0; i < images.length; i++) {
                    var imgContainer = new Image();
                    imgContainer.src = images[i];
                    imgContainer = null;
                }
            }
        };

        // 就是把 rgb(,,)换成了rgba(,,,)
        Util.addOpacity = function(color, opacity) {
            var newColor = color.replace(/rgb/g, "rgba").replace(/\)/g, "," + opacity + ")");
            return newColor;
        };

        Util.isOffline = function() {
            return !navigator.onLine;
        };

        Util.getStorageValue = function(key) {
            var item = window.localStorage.getItem(key);
            if (!item) {
                return;
            }

            item = JSON.parse(item);
            var data = item.data;
            var type = item.type;
            var value = null;
            switch(type) {
                case "Boolean":
                    value = Boolean(data);
                    break;
                case "String":
                    value = String(data);
                    break;
                case "Number":
                    value = Number(data);
                    break;
                case "JSON":
                    value = JSON.parse(data);
                    break;
            }

            return value;
        };

        Util.setStorageValue = function(key, value) {
            var type = null;
            var data = value;
            if (typeof value === "boolean") {
                type = "Boolean";
            } else if (typeof value === "string") {
                type = "String";
            } else if (typeof value === "number") {
                type = "Number";
            } else if (typeof value === "object") {
                type = "JSON";
                data = JSON.stringify(value);
            }

            window.localStorage.setItem(key, JSON.stringify({data: data, type: type}));
        }
    }).();

    module.exports = Util;
});

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注