SOURCE

const isServer = typeof window == "undefined";

/**
 * 返回一个除去了所有false值的 array副本。 在javascript中, false, null, 0, "", undefined 和 NaN 都是false值.
 */

function compact(arr) {
    return arr.filter(x => !!x);
}
/**
 *
 * @param {any} array
 * @returns
 */
function uniq(array) {
    return [...new Set(array)];
}

/**
 * 返回传入的 arrays(数组)并集:按顺序返回,返回数组的元素是唯一的,可以传入一个或多个 arrays (数组)
 */

function union(...arrs) {
    let _arrs = [].concat(...arrs);
    return uniq(_arrs);
}

const on = (function() {
    if (!isServer && document.addEventListener) {
        return function(element, event, handler) {
            if (element && event && handler) {
                element.addEventListener(event, handler, false);
            }
        };
    } else {
        return function(element, event, handler) {
            if (element && event && handler) {
                element.attachEvent("on" + event, handler);
            }
        };
    }
})();

/**
 *
 * ua 检测
 * @returns
 */
function detect() {
    if (isServer) return;

    let { userAgent, platform } = window.navigator;
    var ua = userAgent;
    var os = {},
        browser = {},
        android = ua.match(/(Android);?[\s/]+([\d.]+)?/),
        osx = !!ua.match(/\(Macintosh; Intel /),
        ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
        ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/),
        iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
        webos = ua.match(/(webOS|hpwOS)[\s/]([\d.]+)/),
        win = /Win\d{2}|Windows/.test(platform),
        wp = ua.match(/Windows Phone ([\d.]+)/),
        touchpad = webos && ua.match(/TouchPad/),
        kindle = ua.match(/Kindle\/([\d.]+)/),
        silk = ua.match(/Silk\/([\d._]+)/),
        blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/),
        bb10 = ua.match(/(BB10).*Version\/([\d.]+)/),
        rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/),
        playbook = ua.match(/PlayBook/),
        chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/),
        firefox = ua.match(/Firefox\/([\d.]+)/),
        ie =
            ua.match(/MSIE\s([\d.]+)/) ||
            ua.match(/Trident\/[\d](?=[^?]+).*rv:([0-9.].)/),
        webview =
            !chrome && ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/),
        safari =
            webview ||
            ua.match(
                /Version\/([\d.]+)([^S](Safari)|[^M]*(Mobile)[^S]*(Safari))/
            );

    if (android) (os.android = true), (os.version = android[2]);
    if (iphone && !ipod) {
        os.ios = os.iphone = true;
        os.version = iphone[2].replace(/_/g, ".");
    }
    if (ipad)
        (os.ios = os.ipad = true), (os.version = ipad[2].replace(/_/g, "."));
    if (ipod) {
        os.ios = os.ipod = true;
        os.version = ipod[3] ? ipod[3].replace(/_/g, ".") : null;
    }
    if (wp) (os.wp = true), (os.version = wp[1]);
    if (webos) (os.webos = true), (os.version = webos[2]);
    if (touchpad) os.touchpad = true;
    if (blackberry) (os.blackberry = true), (os.version = blackberry[2]);
    if (bb10) (os.bb10 = true), (os.version = bb10[2]);
    if (rimtabletos) (os.rimtabletos = true), (os.version = rimtabletos[2]);
    if (playbook) browser.playbook = true;
    if (kindle) (os.kindle = true), (os.version = kindle[1]);
    if (silk) (browser.silk = true), (browser.version = silk[1]);
    if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true;
    if (chrome) (browser.chrome = true), (browser.version = chrome[1]);
    if (firefox) (browser.firefox = true), (browser.version = firefox[1]);
    if (ie) (browser.ie = true), (browser.version = ie[1]);
    if (safari && (osx || os.ios || win)) {
        browser.safari = true;
        if (!os.ios) browser.version = safari[1];
    }
    if (webview) browser.webview = true;

    os.tablet = !!(
        ipad ||
        playbook ||
        (android && !ua.match(/Mobile/)) ||
        (firefox && ua.match(/Tablet/)) ||
        (ie && !ua.match(/Phone/) && ua.match(/Touch/))
    );
    os.phone = !!(
        !os.tablet &&
        !os.ipod &&
        (android ||
            iphone ||
            webos ||
            blackberry ||
            bb10 ||
            (chrome && ua.match(/Android/)) ||
            (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
            (firefox && ua.match(/Mobile/)) ||
            (ie && ua.match(/Touch/)))
    );

    browser.special = {
        safari: /Safari/gi.test(navigator.appVersion),
        qq: /MQQBrowser|CriOS/.test(ua),
        baidu: /baidubrowser/.test(ua),
        uc: /UCBrowser/.test(ua)
    };

    browser.weChat = /micromessenger/i.test(ua);

    return {
        os,
        browser
    };
}

/**
 *
 * @returns
 */
function queryObj() {
    let qo = {};
    let arr = location.search.replace(/^\?/, "").split("&");
    for (let _i = 0, _len = arr.length; _i < _len; _i++) {
        let im = arr[_i];
        let kv = im.split("=");
        qo[kv[0]] = kv[1] || "";
    }
    return qo;
}

/**
 * 获取url参数
 * @param {any} string
 * @returns
 */
function queryString(string) {
    var parsed = {};
    string = string !== undefined ? string : window.location.search;

    if (typeof string === "string" && string.length > 0) {
        if (string[0] === "?") {
            string = string.substring(1);
        }

        string = string.split("&");

        for (var i = 0, length = string.length; i < length; i++) {
            var element = string[i],
                eqPos = element.indexOf("="),
                keyValue,
                elValue;

            if (eqPos >= 0) {
                keyValue = element.substr(0, eqPos);
                elValue = element.substr(eqPos + 1);
            } else {
                keyValue = element;
                elValue = "";
            }

            elValue = decodeURIComponent(elValue);

            if (parsed[keyValue] === undefined) {
                parsed[keyValue] = elValue;
            } else if (parsed[keyValue] instanceof Array) {
                parsed[keyValue].push(elValue);
            } else {
                parsed[keyValue] = [parsed[keyValue], elValue];
            }
        }
    }

    return parsed;
}

/**
 * 发送日志
 * @param {any} query
 * @param {string} [type="qianclick"]
 */
function sendLog(query, type = "qianclick") {
    let { os } = detect();

    let hostMap = {
        qianclick: "//click.qianqian.com/v.gif",
        pvlog: "/cms/mobile.gif"
    };

    let params = function(query) {
        let rs = [];
        for (let pro in query) {
            rs.push(
                encodeURIComponent(pro) + "=" + encodeURIComponent(query[pro])
            );
        }
        return rs.join("&");
    };

    let da = +new Date() + parseInt(Math.random() * 1000);
    let img = (window["img_" + da] = new Image());
    //let img_p = window["img_p_" + da] = new Image();

    query = Object.assign(
        {
            pid: 304,
            type: "click",
            ref: "web",
            // os_v: os.version,
            v: "1.0.0",
            r: da,
            page: "home",
            page_url: location.href,
            url: location.href,
            page_refer: document.referrer || "",
            referurl: document.referrer || "",
            channel: queryObj().fr || "",
            UA: navigator.userAgent
        },
        query
    );

    img.onload = img.onerror = img.onabort = function() {
        img.onload = img.onerror = img.onabort = null;
        window["img_" + da] = null;
    };
    img.src = hostMap[type] + "?" + params(query);

    const _hmt = _hmt || [];
    if (
        type == "qianclick" &&
        _hmt &&
        typeof query.page != "undefined" &&
        typeof query.pos != "undefined" &&
        typeof query.sub != "undefined"
    ) {
        _hmt && _hmt.push(["_trackEvent", query.page, query.pos, query.sub]);
    }
}
/**
 * 去空格
 * @param {any} str
 * @returns
 */
function trim(str) {
    return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "");
}

/**
 * 格式化图片路径
 * @param {String} url
 * @param {String} quality
 */
function checkImgUrl(url, quality) {
    var q = quality || "";
    if (url.indexOf(".jpg@") > -1) {
        url = url.substring(0, url.indexOf(".jpg@") + 4) + q;
    } else if (url.indexOf(".JPG@") > -1) {
        url = url.substring(0, url.indexOf(".JPG@") + 4) + q;
    } else if (url.indexOf(".png@") > -1) {
        url = url.substring(0, url.indexOf(".png@") + 4) + q;
    } else if (url.indexOf(".jpeg@") > -1) {
        url = url.substring(0, url.indexOf(".jpeg@") + 5) + q;
    } else if (url) {
        url = url + q;
    }
    return url;
}

/**
 * 时长
 * @param {any} //同时兼容ie和ff的写法
 * @returns
 */

// function getEvent() {
//     if(document.all)  return window.event;    
//     let func=getEvent.caller;      
//     while(func!=null){  
//         var arg0=func.arguments[0]; 
//         if (arg0) { 
//             if((arg0.constructor==Event || arg0.constructor ==MouseEvent) || (typeof(arg0)=="object" && arg0.preventDefault && arg0.stopPropagation))
//             {  
//                 return arg0;
//             } 
//         } 
//         func=func.caller; 
//     } 
//     return null; 
// } 

/**
 * cookie
 * @param {*} sec 
 */
let cookie = {
    set(key,val,time) {//设置cookie方法
        let date = new Date(); //获取当前时间
        let expiresDays = time;  //将date设置为n天以后的时间
        date.setTime(date.getTime()+expiresDays*24*3600*1000); //格式化为cookie识别的时间
        document.cookie=key + "=" + val +";expires="+date.toGMTString();  //设置cookie
    },

    get(key) {//获取cookie方法
        /*获取cookie参数*/
        let getCookie = document.cookie.replace(/[ ]/g,"");  //获取cookie,并且将获得的cookie格式化,去掉空格字符
        let arrCookie = getCookie.split(";")  //将获得的cookie以"分号"为标识 将cookie保存到arrCookie的数组中
        let tips;  //声明变量tips
        for(let i=0;i<arrCookie.length;i++){   //使用for循环查找cookie中的tips变量
            let arr=arrCookie[i].split("=");   //将单条cookie用"等号"为标识,将单条cookie保存为arr数组
            if(key==arr[0]){  //匹配变量名称,其中arr[0]是指的cookie名称,如果该条变量为tips则执行判断语句中的赋值操作
                tips=arr[1];   //将cookie的值赋给变量tips
                break;   //终止for循环遍历
            }
        }
        return tips
    },

    delete(key){ //删除cookie方法
        let date = new Date(); //获取当前时间
        date.setTime(date.getTime()-10000); //将date设置为过去���时间
        document.cookie = key + "=v; expires =" +date.toGMTString();//设置cookie
    }    
}

/**
 * 时长
 * @param {any} sec
 * @returns
 */
function duration(sec) {
    let fix, floor, h, parseMinites;
    sec = Math.ceil(sec);
    fix = function(num) {
        if (num < 10) {
            return "0" + num;
        } else {
            return num;
        }
    };
    floor = function(num) {
        return Math.floor(num);
    };
    parseMinites = function(sec) {
        var m, s;
        m = floor(sec / 60);
        s = sec % 60;
        return fix(m) + ":" + fix(s);
    };
    if (!sec) {
        return "00:00";
    } else if (sec < 60) {
        return "00:" + fix(sec);
    } else if (sec < 3600) {
        return parseMinites(sec);
    } else {
        h = floor(sec / 3600);
        return fix(h) + ":" + parseMinites(sec % 3600);
    }
}

let storageFuns = {
    getStorage: function(k) {
        return localStorage.getItem(k);
    },
    setStorage: function(k, v, expires) {
        if (expires) {
            expires = +new Date() + expires;
            v = [v, expires];
        }
        localStorage.setItem(k, JSON.stringify(v));
    },
    removeStorage: function(k) {
        localStorage.removeItem(k);
    }
};

/**
 * 解析sondid
 * @param {any} songIdx
 * @returns
 */
function decodeSongIdx(songIdx) {
    //解析id
    let songIdHexLen = ~~songIdx.substr(2, 2);
    let songIdHex = songIdx.substr(4, songIdHexLen);
    if (songIdHexLen !== songIdHex.length) return 0;

    let updateTimeHexLen = songIdx.substr(songIdHexLen + 4, 2);
    let updateTimeHex = songIdx.substr(songIdHexLen + 6);
    if (updateTimeHexLen.substr(0, 1) === "0") {
        updateTimeHexLen = updateTimeHexLen.substr(1, 1);
    }
    updateTimeHexLen = ~~updateTimeHexLen;
    if (updateTimeHexLen !== updateTimeHex.length) return 0;

    let songId = parseInt(songIdHex, 16);
    let songIdHash = ~~songIdx.substr(0, 2);
    if (songId % 99 !== songIdHash) return 0;

    return songId;
}

/**
 *判断字符串是否是Json格式20190119add@yuting@taihe.com
 *@param {any} str
 *@returns
 */
function isJSON(str) {
    if (typeof str == "string") {
        try {
            var obj = JSON.parse(str);
            if (typeof obj == "object" && obj) {
                return true;
            } else {
                return false;
            }
        } catch (e) {
            return false;
        }
    }
}
console 命令行工具 X clear

                    
>
console