工具函数

571 阅读7分钟

1. DOM操作

是否有class

/*
* @desc 是否有class 
* @param {Object} obj 
* @param {String} cls 
* @returns {Boolean} 
*/
function hasClass(obj, cls) {
    cls = cls.replace(/^\s|\s$/g, "")
    return (" " + ((obj || {}).className || "").replace(/\s/g, " ") + " ").indexOf(" " + cls + " ") >= 0;
}

添加class

/*
* @desc 添加class 
* @param {Object} obj 
* @param {String} cls 
*/
function addClass(obj, cls) {
    if (!this.hasClass(obj, cls)) obj.className += " " + cls;
}

删除class

删除class
/*
* @desc 删除class 
* @param {Object} obj 
* @param {String} cls 
*/
function removeClass(obj, cls) {
    cls = cls.replace(/^\s|\s$/g, "");

    if ((" " + ((obj || {}).className || "").replace(/\s/g, " ") + " ").indexOf(" " + cls + " ") >= 0) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        obj.className = obj.className.replace(reg, ' ');
    }
}

获取指定元素的子元素

/*
* 获取指定元素的子元素 
* @param {object} curEle 
* @param {string} tagName 
* @returns {Array} 
*/
function children (curEle, tagName) {
    var nodeList = curEle.childNodes;
    var ary = [];
    if (/MSIE(6|7|8)/.test(navigator.userAgent)) {
        for (var i = 0; i < nodeList.length; i++) {
            var curNode = nodeList[i];
            if (curNode.nodeType === 1) {
                ary[ary.length] = curNode;
            }
        }
    } else {
        ary = Array.prototype.slice.call(curEle.children);
    }

    // 获取指定子元素
    if (typeof tagName === "string") {
        for (var k = 0; k < ary.length; k++) {
            var curTag = ary[k];
            if (curTag.nodeName.toLowerCase() !== tagName.toLowerCase()) {
                ary.splice(k, 1);
                k--;
            }
        }
    }

    return ary;
}

2. 本地缓存

sessionStorage

存储

/*
 * 存储
 * @param {string} name - 名称
 * @param {string} content - 内容
 */
function setStore(name, content) {
    if (!name) return;

    if (typeof content !== "string") {
        content = JSON.stringify(content);
    }

    sessionStorage.setItem(name, content);
};

获取

/*
 * 获取
 * @param {string} name - 名称
 * @returns {string} 内容
 */
function getStore(name) {
    if (!name) return;

    var content = sessionStorage.getItem(name);

    try {
        content = JSON.parse(content);
        return content;
    } catch (e) {
        return content;
    }
};

删除

/*
 * 删除
 * @param {string} name - 名称
 */
function removeStore(name) {
    if (!name) return;
    sessionStorage.removeItem(name);
};

3. 身份证

根据身份证获取出生日期、性别、年龄

/*
* 根据身份证获取出生日期、性别、年龄
* @param {string} idcard - 身份证号
* @returns {object} object.birth - 生日 object.gender - 性别 object.age - 年龄
*/
function getIdCardInfo(idcard) {
    var isIdcard = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;

    var birth = '';
    var birthYear = '';
    var birthMonth = '';
    var birthDay = '';
    var gender = '';
    var age = '';

    if (isIdcard.test(idcard)) {
        // 获取当前日期
        var curDate = new Date();
        var curMonth = curDate.getMonth() + 1;
        var curDay = curDate.getDate();

        if (idcard.length === 18) {// 18位身份证
            birthYear = idcard.substring(6, 10);
            birthMonth = idcard.substring(10, 12);
            birthDay = idcard.substring(12, 14);

            gender = idcard.substring(16, 17);
        } else if (idcard.length === 15) {// 15位身份证
            birthYear = "19" + idcard.substring(6, 8);
            birthMonth = idcard.substring(8, 10);
            birthDay = idcard.substring(10, 12);

            gender = idcard.substring(14, 15);
        }

        birth = birthYear + "-" + birthMonth + "-" + birthDay;
        gender = gender % 2 ? "男" : "女";// 1代表男性,2代表女性

        age = curDate.getFullYear() - birthYear - 1;

        if (idcard.substring(10, 12) < curMonth || idcard.substring(10, 12) == curMonth && idcard.substring(12, 14) <= curDay) {
            age++;
        }

        return {
            birth: birth,
            gender: gender,
            age: age,
        }
    } else {
        return {
            birth: '',
            gender: '',
            age: '',
        }
    }
}

4. 字符串

去除富文本格式

/*
 * 去除富文本格式
 * @param str {string} - url地址
 * @returns {string} - 去除富文本格式的文本
 */
function  richFilter(str) {
    str = str.replace(/(\n)/g, "");    
    str = str.replace(/(\t)/g, "");    
    str = str.replace(/(\r)/g, "");    
    str = str.replace(/<\/?[^>]*>/g, "");    
    str = str.replace(/\s*/g, ""); 
    
    return str;
}

获取文件后缀名

/*
 * 获取文件后缀名
 * @param thumbUrl {string} - url地址
 */
function  getResourceSuffix (file) {
    if (file) {
        let suffixIndex1 = file.lastIndexOf(".");
        let suffixIndex2 = file.length;
 
        return file.substring(suffixIndex1 + 1, suffixIndex2).toLowerCase(); //后缀名
    } else {
        return '';
    }
}

清除字符串首尾空格

/*
* 清除字符串首尾空格
* @param str {string} - 字符串
*/
function trim(str) {
    if (str) {
        return str.replace(/(^\s*)|(\s*$)/g, "");
    } else {
        return '';
    }
}

补全资源url地址

/*
 * 补全资源url地址
 * @param resourceUrl {string} - url地址
 * @param baseUrl {string} - 网站地址
 * @returns {*}
 */
function fullResourceUrl(resourceUrl,baseUrl) {
    let regUrl = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/;
 
    if (!resourceUrl) {
        return '';
    }

    let resourceUrlTemp = resourceUrl.replace(/(^\s*)|(\s*$)/g, "");
    if (!resourceUrlTemp) {
        return '';
    }

    if (regUrl.test(resourceUrlTemp)) {
        return resourceUrl;
    } else {
        // 处理电话、邮件、信息和定位
        if (resourceUrlTemp.startsWith('tel:') || resourceUrlTemp.startsWith('mailto:') || resourceUrlTemp.startsWith('sms:') || resourceUrlTemp.startsWith('geopoint:')) {
            return resourceUrlTemp;
        } else if (resourceUrlTemp.startsWith('/')) {
            return baseUrl + resourceUrl;
        } else {
            return baseUrl + '/' + resourceUrl;
        }
    }
};

字符串下划线转小驼峰

操作字符串数组

/*
* 操作字符串数组
* @param str {string} - 字符串
*/
function tranformStr(str){
    var strArr=str.split('-');
    for(var i=1;i<strArr.length;i++){
        strArr[i]=strArr[i].charAt(0).toUpperCase()+strArr[i].substring(1);
    }
    return strArr.join('');
}

操作字符数组

/*
* 操作字符数组
* @param str {string} - 字符串
*/
function tranformStr(str){
    var strArr=str.split('');
    for(var i=1;i<strArr.length;i++){
        if(strArr[i]=='-'){
            //删除'-'
            strArr.splice(i,1);
            //转大写
            if(i<strArr.length){
                strArr[i]=strArr[i].toUpperCase();
            }
        }
    }
    return strArr.join('');
}

利用正则表达式

function transformStr3(str){
    var re=/-(\w)/g;
    return str.replace(re,function ($0,$1){
        return $1.toUpperCase();
    });
}

数组转字符串

/*
* 数组转字符串
* param {Array} arr
* param {string} sp
*/
function arrToStr(arr,sp){
    return arr.jion(sp);
}

json序列化

/*
* json序列化
* @param str {json} - 序列化json
*/
function json2Form(json) {
    var str = [];
    for (var p in json) {
        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(json[p]));
    }
    return str.join("&");
},

判断字符是否为空

/*
* 判断字符是否为空
* @param str {string} - 字符串
*/
function isEmpty(str) {
    if (str == null || str == '' || typeof (str) == "undefined") {
        return true;
    } else {
        return false;
    }
}

字符串超出长度显示...(省略号)

/* 
 * 用途:js中字符串超长作固定长度加省略号(...)处理
 * 参数说明:
 * str:需要进行处理的字符串,可含汉字
 * len:需要显示多少个汉字,两个英文字母相当于一个汉字。
 */
function beautySub(str, len) {
    var reg = /[\u4e00-\u9fa5]/g, //专业匹配中文
        slice = str.substring(0, len),
        chineseCharNum = (~~(slice.match(reg) && slice.match(reg).length)),
        realen = slice.length * 2 - chineseCharNum;
    return str.substr(0, realen) + (realen < str.length ? "..." : "");
}

token生成

/**
 * token生成
 * @param {Number} len - token长度
 * @returns {String} token
 */
function randomString (len) {
    len = len || 16;
    var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
    /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
    var maxPos = $chars.length;
    var pwd = '';
    for (i = 0; i < len; i++) {
        pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return pwd;
}

手机号隐藏中间几位号码

/*
 * 手机号码隐藏中间四位
 * @param {Number} phone - 手机号
 * @returns {String} 处理后的手机号码
 */
function formatPhone(phone){
    if(phone) {
        var regPhone= /(\d{4})\d{4}(\d{3})/;
        var phone= phone.replace(regPhone,"$1****$2");
        return phone;
    } else {
        return null;
    }
}

判断一个字符串中某个字符出现的次数

/*
 * 判断一个字符串中某个字符出现的次数
 * @param string 目标字符串
 * @param ele  字符
 * @returns {number}  处理后的次数
 */
function calConunts(string,ele) {
    var count = 0,
        pos = string.indexOf(ele);
    while(pos !== -1) {
        count++;
        pos = string.indexOf(ele,pos + 1);
    }
    return count;
}

5. 浏览器

获取地址栏参数

 /*
 * 获取地址栏参数
 * @param {string} name - 参数名
 * @returns {string} 参数值
 */
function getQueryString(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
    var r = window.location.search.substr(1).match(reg);
    if (r != null) return decodeURI(r[2]);
    return null;
}

/**
 * 获取地址栏参数(防止xss攻击)
 * @param {string} name - 参数名
 * @returns {string} 参数值
 */
function getQueryString(name) {
  var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
  var r = window.location.search.substr(1).match(reg);
  if (r != null) {
      return decodeURI(r[2]).replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, "&quot;").replace(/'/g, "&#039;");//防止xss攻击
   } else {
       return null;
   }
}

删除地址栏参数

/*
 * 删除地址栏参数
 * @param {string} name - 参数名
 * @returns {string} 地址
 */
function funcUrlDel(name) {
    var loca = window.location;
    var baseUrl = loca.origin + loca.pathname + "?";
    var query = loca.search.substr(1);
    if (query.indexOf(name) > -1) {
        var obj = {}
        var arr = query.split("&");
        for (var i = 0; i < arr.length; i++) {
            arr[i] = arr[i].split("=");
            obj[arr[i][0]] = arr[i][1];
        }
        delete obj[name];
        var url = baseUrl + JSON.stringify(obj).replace(/[\"\{\}]/g, "").replace(/\:/g, "=").replace(/\,/g, "&");
        return url
    }
}

禁用浏览器后退操作

可以消除浏览器当前页面所有的后退操作,包括键盘、鼠标手势等产生的后退动作。 在常用浏览器中都可以禁用后退

history.pushState(null, null, document.URL);
window.addEventListener('popstate', function () {
    history.pushState(null, null, document.URL);)
};

获取运行环境

/**
 *  判断浏览器环境
 *  browser.isQQBrw && browser.isQQ QQ APP中
 *  browser.isQQBrw && !browser.isQQ QQ 浏览器中
 */
var browserUtil = {
    versions: function () {
        var u = navigator.userAgent,
            app = navigator.appVersion;
        return {
            mobile: !!u.match(/AppleWebKit.*Mobile.*/), // 是否为移动终端
            ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios终端
            android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1 // android终端
        };
    }(),
    isWeiXin: function () {
        var ua = navigator.userAgent.toLowerCase();
        if (ua.match(/MicroMessenger/i) == "micromessenger") { // 在微信中打开
            return true;
        } else {
            return false;
        }
    }(),
    isQQ: function () {
        var ua = navigator.userAgent.toLowerCase();
        if (ua.match(/ QQ/i) == " qq") { // QQ APP中才有的标识
            return true;
        } else {
            return false;
        }
    }(),
    isQQBrw: function () {
        var u = navigator.userAgent;
        if (u.indexOf('MQQBrowser') > -1) {  // QQ APP和 QQ浏览器中都有的标识
            return true;
        } else {
            return false;
        }
    }(),
    isWeiBo: function () {
        var ua = navigator.userAgent.toLowerCase();
        if (ua.match(/WeiBo/i) == "weibo") { // 在新浪微博客户端打开
            return true;
        } else {
            return false;
        }
    }(),
    language: (navigator.browserLanguage || navigator.language).toLowerCase()
}

关闭浏览器当前窗口

function closeWebPage() {
    if (navigator.userAgent.indexOf("MSIE") > 0) {
        if (navigator.userAgent.indexOf("MSIE 6.0") > 0) {
            window.opener = null;
            window.close();
        } else {
            window.open('', '_top');
            window.top.close();
        }
    } else if (navigator.userAgent.indexOf("Firefox") > 0) {
        window.location.href = 'about:blank '; //火狐默认状态非window.open的页面window.close是无效的
    } else {
        window.opener = null;
        window.open('', '_self', '');
        window.close();
    }
}

7. 日期

日期格式化

/*
 * 日期格式化
 * @param {string} date - 日期
 * @param {string} fmt - 需要的日期格式
 * @returns {string} - 符合格式的日期
 */
function formatDate(date, fmt = "yyyy-MM-dd HH:mm:ss") {
    if (date) {
        let fullDate = new Date(date.replace(/-/g, '/'));
 
        let o = {
            "M+": fullDate.getMonth() + 1,// 月份
            "d+": fullDate.getDate(),// 日
            "H+": fullDate.getHours(),// 小时
            "m+": fullDate.getMinutes(),// 分
            "s+": fullDate.getSeconds(),// 秒
            "q+": Math.floor((fullDate.getMonth() + 3) / 3), // 季度
            "S": fullDate.getMilliseconds()// 毫秒
        };
 
        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (fullDate.getFullYear() + "").substr(4 - RegExp.$1.length));
        }
 
        for (let k in o) {
            if (new RegExp("(" + k + ")").test(fmt)) {
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
            }
        }
        return fmt;
    } else {
        return "";
    }
}

加减时间

/**
 * yyyy-MM-dd HH-mm-ss 加减时间
 * @param {string} date - yyyy-MM-dd HH-mm-ss
 * @param {object} diff - 加减的单位和长度
 *                 diff.years - 年
 *                 diff.months - 月
 *                 diff.days - 日
 *                 diff.hours - 时
 *                 diff.minutes - 分
 *                 diff.seconds - 秒
 *                 diff.milliseconds - 毫秒
 * @returns {string} - yyyy-MM-dd HH:mm:ss
 */
function diffDate(date, diff, fmt = "yyyy-MM-dd HH:mm:ss") {
    if (date) {
        let fullDate = new Date(date.replace(/-/g, '/'));

        if (diff) {
            if (diff.years) {
                fullDate.setFullYear(fullDate.getFullYear() + diff.years);
            }

            if (diff.months) {
                fullDate.setMonth(fullDate.getMonth() + diff.months);
            }

            if (diff.days) {
                fullDate.setDate(fullDate.getDate() + diff.days);
            }

            if (diff.hours) {
                fullDate.setHours(fullDate.getHours() + diff.hours);
            }

            if (diff.minutes) {
                fullDate.setMinutes(fullDate.getMinutes() + diff.minutes);
            }

            if (diff.seconds) {
                fullDate.setSeconds(fullDate.getSeconds() + diff.seconds);
            }

            if (diff.milliseconds) {
                fullDate.setMilliseconds(fullDate.getMilliseconds() + diff.milliseconds);
            }
        }

        let o = {
            "M+": fullDate.getMonth() + 1,// 月份
            "d+": fullDate.getDate(),// 日
            "H+": fullDate.getHours(),// 小时
            "m+": fullDate.getMinutes(),// 分
            "s+": fullDate.getSeconds(),// 秒
            "q+": Math.floor((fullDate.getMonth() + 3) / 3), // 季度
            "S": fullDate.getMilliseconds()// 毫秒
        };

        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (fullDate.getFullYear() + "").substr(4 - RegExp.$1.length));
        }

        for (let k in o) {
            if (new RegExp("(" + k + ")").test(fmt)) {
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
            }
        }
        return fmt;
    } else {
        return '';
    }
}

获取日期加减n天后的日期

/**
 * yyyy-MM-dd HH-mm-ss转换成yyyy-MM-dd
 * @param {string} date - yyyy-MM-dd HH-mm-ss
 * @param {string} days - 加减的天数
 * @returns {string} - yyyy-MM-dd
 */
function diffDate(date, days) {
    if (date) {
        var date = new Date(date.replace(/-/g, '/'));
 
        if (days) {
            date.setDate(date.getDate() + days);
        }
 
        var myYear = date.getFullYear();
        var myMonth = date.getMonth() + 1;
        var myDate = date.getDate();
 
        myMonth = myMonth < 10 ? "0" + myMonth : myMonth;
        myDate = myDate < 10 ? "0" + myDate : myDate;
 
        var formatDate = myYear + "-" + myMonth + "-" + myDate;
             
        return formatDate;
    } else {
        return null;
    }
}

获取日期加减n月后的日期

/**
 * yyyy-MM-dd HH-mm-ss转换成yyyy-MM-dd
 * @param {string} date - yyyy-MM-dd HH-mm-ss
 * @param {string} days - 加减的月数
 * @returns {string} - yyyy-MM
 */
function diffDate(date, months) {
    if (date) {
        var date = new Date(date.replace(/-/g, '/'));
 
        if (months) {
            date.setMonth(date.getMonth() + months);
        }
 
        var myYear = date.getFullYear();
        var myMonth = date.getMonth() + 1;
 
        myMonth = myMonth < 10 ? "0" + myMonth : myMonth;
 
        var formatDate = myYear + "-" + myMonth;
             
        return formatDate;
    } else {
        return null;
    }
}

日期格式转换为时间戳

/**
* 日期格式转换为时间戳
* @param {String} date - 日期 yyyy-MM-dd HH-mm-ss
* @returns {Number} - 时间戳,单位s
*/
function dateToUnix(date){
    if (date) {
        var date = date.replace(/-/g, '/'); // 将yyy-mm-dd格式装换成yyyy/mm/dd
        return Date.parse(new Date(date)) / 1000; // parseDate.parse()支持yyyy/mm/dd格式的毫秒数返回
    } else{
        return null;
    }
}

时间戳转换为日期格式

/**
* 时间戳转换为日期格式
* @param {String} unix - 时间戳,单位s
* @param {Boolean} needhms - 是否需要HH-mm-ss
* @returns {Number} 时间戳
*/
function unixToDate(unix, fmt){
    fmt = fmt || "yyyy-MM-dd";
 
    var fullDate = new Date(parseInt(unix) * 1000);

    var o = {
        "M+": fullDate.getMonth() + 1,// 月份
        "d+": fullDate.getDate(),// 日
        "H+": fullDate.getHours(),// 小时
        "m+": fullDate.getMinutes(),// 分
        "s+": fullDate.getSeconds(),// 秒
        "q+": Math.floor((fullDate.getMonth() + 3) / 3), // 季度
        "S": fullDate.getMilliseconds()// 毫秒
    };

    if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (fullDate.getFullYear() + "").substr(4 - RegExp.$1.length));
    }

    for (var k in o) {
        if (new RegExp("(" + k + ")").test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        }
    }
    return fmt;
}

时间戳拆分

/*
* 时间戳拆分
* @param unix - 时间戳,单位s
* @returns {Object} year: number, month: number, date: number, hour: number, minute: number, second: number
*/
function apartDatetime(unix) {
    var now = new Date(parseInt(unix) * 1000);
    var year = now.getFullYear();
    var month = now.getMonth() + 1;
    var date = now.getDate();
    var hour = now.getHours();
    var minute = now.getMinutes();
    var second = now.getSeconds();
 
    return {
        year: year,
        month: month,
        date: date,
        hour: hour,
        minute: minute,
        second: second
    }
}

倒计时

 /**
  * 当前时间距离结束时间的倒计时
  * @param {number} endTime - 结束日期时间戳
  * @param {number} startTime - 开始日期时间戳
  * @returns {string} diff - 相差的秒数
  *                   days - 相差的天数
  *                   hours - 相差的小时数
  *                   minutes - 相差的分钟数
  *                   seconds - 相差的秒数
  */
 function getDiffTime(endTime, startTime) {
     if (!endTime || !startTime) {
         return '';
     }

     var timeDiff = endTime - startTime;
     if (timeDiff <= 0) {
         return {
             diff: 0,
             days: '00',
             hours: '00',
             minutes: '00',
             seconds: '00',
         };
     }

     var days = parseInt(timeDiff / 60 / 60 / 24, 10); //计算剩余的天数
     var hours = parseInt(timeDiff / 60 / 60 % 24, 10); //计算剩余的小时
     var minutes = parseInt(timeDiff / 60 % 60, 10); //计算剩余的分钟
     var seconds = parseInt(timeDiff % 60, 10); //计算剩余的秒数

     days = days < 10 ? '0' + days : days;
     hours = hours < 10 ? '0' + hours : hours;
     minutes = minutes < 10 ? '0' + minutes : minutes;
     seconds = seconds < 10 ? '0' + seconds : seconds;

     return {
         diff: timeDiff,
         days: days,
         hours: hours,
         minutes: minutes,
         seconds: seconds,
     }
 }

8. 函数

函数防抖 (只执行最后一次点击)

/*
 * 函数防抖 (只执行最后一次点击)
 * @param fn
 * @param delay
 * @returns {Function}
 * @constructor
 */
function Debounce(fn, t) {
    var delay = t || 500;
    var timer;

    return function () {
        let args = arguments;
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            timer = null;
            fn.apply(this, args);
        }, delay);
    }
}

函数节流

/*
 * 函数节流
 * @param fn
 * @param interval
 * @returns {Function}
 * @constructor
 */
function Throttle(fn, t) {
    var last;
    var timer;
    var interval = t || 500;

    return function () {
        var args = arguments;
        var now = +new Date();
        if (last && now - last < interval) {
            clearTimeout(timer);
            timer = setTimeout(() => {
                last = now;
                fn.apply(this, args);
            }, interval);
        } else {
            last = now;
            fn.apply(this, args);
        }
    }
}

9. 数据处理

将有层级关系一维数组转换成二维数组