这是我自己项目开发过程中对于复用性比较高的一些常用函数和正则的封装,最新代码请已gitee为准,如有疑问或bug欢迎讨论(更新时间:2021-08-03)
gitee地址
1.es6开发版
/**
* 常用函数封装
* author: slongzhang
* date: 2021-01-06
*/
( function( global, factory ) {
"use strict";
if ( typeof module === "object" && typeof module.exports === "object" ) {
// For CommonJS and CommonJS-like environments where a proper `window`
// is present, execute the factory and get zslBase.
// For environments that do not have a `window` with a `document`
// (such as Node.js), expose a factory as module.exports.
// This accentuates the need for the creation of a real `window`.
// e.g. var zslBase = require("zslBase")(window);
// See ticket #14549 for more info.
module.exports = global.document ?
factory( global, true ) :
function( w ) {
if ( !w.document ) {
throw new Error( "zslBase requires a window with a document" );
}
return factory( w );
};
} else {
factory( global );
}
// Pass this if window is not defined yet
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
"use strict";
// 正则需要转义的字符
let regEscapeCharacter = ['$','(',')','*','+','.','[',']','?','\\','/','^','{','}','!','|'];
// 判断是否为空
let _empty = function(_value){
var result = true;// 默认不为空
if(_value === null){
result = true;
}
else if(typeof(_value) === 'object'){
result = Object.keys(_value).length>0?false:true;
}
else{
// 0的判断采用php empty弱判断数字0和字符串0都判断为假
if( _value == 0 ){
result = true;
}else{
result = _value?false:true;
}
}
return result;
}
// 合成模板内部函数
let _compileHtml = function(_template){
const evalExpr = /<%=(.+?)%>/g;
const expr = /<%([\s\S]+?)%>/g;
_template = _template
.replace(evalExpr, '`); \n echo( $1 ); \n echo(`')
.replace(expr, '`); \n $1 \n echo(`');
_template = 'echo(`' + _template + '`);';
let script = `(function parse(data){
let output = "";
function echo(html){
output += html;
}
${
_template }
return output;
})`;
return script;
}
let zslBase = {
};
zslBase.version = "1.0.1";
zslBase.author = 'slongzhang@qq.com';
/**
* 加载后才执行
* _fn function 一个可执行函数
*/
zslBase.ready = function(_fn){
if(typeof _fn !== 'function'){
throw 'Fn is not a function!';
}
function completed() {
document.removeEventListener( "DOMContentLoaded", completed );
window.removeEventListener( "load", completed );
_fn();
}
if ( document.readyState === "complete" ||
( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
window.setTimeout( _fn );
} else {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", completed );
// A fallback to window.onload, that will always work
window.addEventListener( "load", completed );
}
}
/**
* 判断是否json字符串
* _str String
* return boolean
.*/
zslBase.isJson = function(_str){
if (typeof _str === 'string') {
try {
JSON.parse(_str);
return true;
} catch(e) {
}
}
return false;
}
/**
* 判断是否是数字
* val All 任意要检查的变量
* return Boolean 返回ture Or false
.*/
zslBase.isNumeric = function(_val){
// isNaN()函数 把空串 空格 以及NUll 按照0来处理 所以先去除
// if(_val === "" || _val === null){
// return false;
// }
// if(!isNaN(_val)){
// //对于空数组和只有一个数值成员的数组或全是数字组成的字符串,isNaN返回false,例如:'123'、[]、[2]、['123'],isNaN返回false,
// //所以如果不需要_val包含这些特殊情况,则这个判断改写为if(!isNaN(_val) && typeof _val === 'number' )
// return true;
// }else{
// return false;
// }
return _val !== "" && _val !== null && !isNaN(_val);
}
/**
* trim基础函数
* _string String 要处理的原始字符串
* _charlist String 要去除的字符
* _type Integer 去除类型:0两边,1:左边,2右边
.*/
let _trimBase = function(_string,_charlist,type = 0){
if(typeof _string !== 'string'){
return _string;
}
if(typeof _charlist === 'undefined'){
if(type === 1){
return _string.replace(/^\s+/gm,'');
}
else if(type === 2){
return _string.replace(/\s+$/gm,'');
}
else{
return _string.replace(/^\s+|\s+$/gm,'');
}
}
_charlist = _charlist.split('');
let zy = regEscapeCharacter,ps='';
for(let item of _charlist){
if(zy.includes(item)){
ps +='\\';
}
ps+=item;
}
let reg;
if(type === 1){
reg = new RegExp("\^"+ps+"+","gm");
}
else if(type === 2){
reg = new RegExp(ps+"+$","gm");
}
else{
reg = new RegExp("\^"+ps+"+|"+ps+"+$","gm");
}
return _string.replace(reg,'');
}
// 移除两侧指定字符
zslBase.trim = function(_string,_charlist){
return _trimBase(_string,_charlist,0);
}
// 移除左侧指定字符
zslBase.ltrim = function(_string,_charlist){
return _trimBase(_string,_charlist,1);
}
// 移除右侧指定字符
zslBase.rtrim = function(_string,_charlist){
return _trimBase(_string,_charlist,2);
}
// 判断变量类型
zslBase.checkType = function(any){
return Object.prototype.toString.call(any).slice(8, -1);
}
// 变量深拷贝
zslBase.varClone = function(any){
let result;
switch(zslBase.checkType(any)) {
case 'Object':
// 拷贝对象
result = {
};
for (let key in any) {
result[key] = zslBase.varClone(any[key]);
}
break;
case 'Array':
// 拷贝数组
result = [];
for (let item of any) {
result.push(zslBase.varClone(item));
}
break;
case 'Function':
result = new Function('return ' + any.toString()).call(this);
break;
case 'Date':
result = new Date(any.valueOf());
break;
case 'RegExp':
result = new RegExp(any);
break;
case 'Map':
result = new Map();
any.forEach((v,k) => {
result.set(k, zslBase.varClone(v));
});
break;
case 'Set':
result = new Set();
for (let val of any.values()) {
result.add(zslBase.varClone(val));
}
break;
default:
result = any;
}
return result;
}
/**
* 获取时间戳,默认毫秒
* _type boolean 默认false输出到毫秒,true则输出到秒
.*/
zslBase.time = function(_type){
var timestemp = (new Date()).valueOf();
if(_type){
// 返回秒
timestemp = parseInt(timestemp/1000);
}
return timestemp;
}
/**
* 时间计算器
* string String|Integer 日期格式字符串或毫秒时间戳
* time String|Integer|Object 时间字符串|时间戳|new Date()出来的时间对象
* toms Boolean 转换为秒的时间戳
* 模拟php的strtotime,但未适配日期时间转时间戳,如需处理如 '2021-01-06'转时间戳请使用'0 s'方法如('0 s','2021-01-06')或直接使用new Date('2021-01-06').valueOf();
.*/
zslBase.strtotime = function(string, time, toSecond = false){
let date, timestamp;
// 判断string, time参数是否存在
if (typeof string === 'undefined' && typeof time === 'undefined') {
// 全部为空,返回当前时间戳
return new Date().valueOf();
}
// 如果不为空,有参数传入,判断第一个参数string 是不是时间对象或符合时间正则
let datetimeRegExp = /^([1-2]\d{3})-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2][0-9]|30|31) (0?\d|1\d|2[0-4]):(0?\d|[1-5]\d):(0?\d|[1-5]\d)$/; // 日期 + 时间
let dateRegExp = /^([1-2]\d{3})-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2][0-9]|30|31)$/; // 纯日期
if (zslBase.checkType(string) === 'Date' || datetimeRegExp.test(string) || dateRegExp.test(string)) {
// 如果第一个参数是日期格式则,time参数变成了toSecond;
if (dateRegExp.test(string)) {
string += ' 00:00:00';// 防止日期小于10导致的读取0点与标准读取格林8点的问题
}
timestamp = new Date(string).valueOf();
return time? parseInt(timestamp / 1000): timestamp;
}
// 进行时间计算
if (!time || time === 'now') {
date = new Date();
timestamp = date.valueOf();
}
else {
date = new Date(time);
timestamp = date.valueOf();
}
let values,unitNames;
try {
// 提取数值和单位,只保留数字和加减点
values = string.replace(/[^\d-+.]+/g,'_#_').split('_#_').filter(function (s) {
return s && parseInt(s);
});
// 单位名,只保留纯字母
unitNames = string.replace(/[^\a-zA-Z]+/g,'_#_').split('_#_').filter(function (s) {
return s && s.trim();
});
// 正则无法匹配到计算规则,则不符合我们参数要求,抛出异常给用户
if (values.length === 0 || unitNames.length === 0) {
throw '';
}
} catch(error) {
throw "参数格式错误,请参照 a b a b ……,a:正负数整型,b:单位year(y年),month(m月),week(w周),day(d日),hours(h时),minutes(i分),seconds(s秒)\r\n如: '2 day -1 hours'=》47小时后\r\n如: '-2 day 1 hours'=》47小时前";
}
let uniqueUnit = {
},temp;
for(let ii = 0; ii < values.length; ii++){
if(unitNames[ii] === 'minutes'){
unitNames[ii] = 'i';
}
if(unitNames[ii] && !uniqueUnit.hasOwnProperty(unitNames[ii][0])){
let val = parseInt(values[ii]);
uniqueUnit[unitNames[ii][0]] = 1;// 取单位的首字母
switch(unitNames[ii]){
case 'y':
// no break;
case 'year':
temp = new Date(timestamp);
temp.setFullYear(temp.getFullYear() + val);
timestamp = temp.valueOf();
break;
case 'm':
// no break;
case 'month':
temp = new Date(timestamp);
temp.setMonth(temp.getMonth() + val);
timestamp = temp.valueOf();
break;
case 'w':
// no break;
case 'week':
timestamp += val*604800000;
break;
case 'd':
// no break;
case 'day':
timestamp += val*86400000;
break;
case 'h':
// no break;
case 'hours':
timestamp += val*3600000;
break;
case 'i':
// no break;
case 'minutes':
timestamp += val*60000;
break;
case 's':
// no break;
case 'seconds':
timestamp += val*1000;
break;
}
}
}
return toSecond? parseInt(timestamp / 1000): timestamp;
}
/**
* 获取指定日期格式(代完善)
* _format String|Integer 日期格式字符串"Y-m-d H:i:s"或毫秒时间戳
* _time String|int|object 时间字符串|时间戳|new Date()出来的时间对象
.*/
zslBase.date = function(format = 'Y-m-d H:i:s', time = new Date()){
if (zslBase.checkType(format) === 'Date') {
time = zslBase.varClone(format);
format = 'Y-m-d H:i:s';
} else if (zslBase.checkType(format) === 'Number') {
time = new Date(format);
format = 'Y-m-d H:i:s';
} else {
if (zslBase.checkType(format) !== 'String') {
throw '参数错误';
}
time = new Date(time);
if(time.toString() === 'Invalid Date'){
time = new Date(null);
}
}
// 得到"Wed Apr 07 2021" => ['Wed','Apr','07','2021']
let dateString = time.toDateString().split(' ');
// 补位函数
let strPad = function(v,len = 2){
let vLen = v.toString().length;
if(vLen < len){
for(let i = len-vLen; i > 0; i--){
v = '0'+v;
}
}
return v;
}
let result = [],temp;
let len = format.length;
for(let ii = 0; ii < len; ii++){
if(format[ii] === '\\'){
result.push(format[++ii]);
continue;
}
switch(format[ii]){
case 'd':
// 一个月中的第几天(从 01 到 31)
result.push(strPad(time.getDate()));
break;
case 'D':
// 星期几的文本表示(用三个字母表示)
result.push(dateString[0]);
break;
case 'j':
// 一个月中的第几天,不带前导零(1 到 31)
result.push(time.getDate());
break;
// case 'l':
// // ('L' 的小写形式)- 星期几的完整的文本表示
// break;
case 'N':
// 星期几的 ISO-8601 数字格式表示(1表示Monday[星期一],7表示Sunday[星期日])
result.push(time.getDay()+1);
break;
// case 'S':
// // 一个月中的第几天的英语序数后缀(2 个字符:st、nd、rd 或 th。与 j 搭配使用)
// break;
case 'w':
// 星期几的数字表示(0 表示 Sunday[星期日],6 表示 Saturday[星期六])
result.push(time.getDay());
break;
case 'z':
// 一年中的第几天(从 0 到 365)
result.push(Math.ceil((new Date(time.toDateString()) - new Date(time.getFullYear().toString()))/(24*60*60*1000)));
break;
case 'W':
// 用 ISO-8601 数字格式表示一年中的第几个星期(第几周)
result.push(Math.ceil(Math.ceil((new Date(time.toDateString()) - new Date(time.getFullYear().toString()))/(24*60*60*1000))/7));
break;
// case 'F':
// // 月份的完整的文本表示(January[一月份] 到 December[十二月份])
// break;
case 'm':
// 月份的数字表示(从 01 到 12)
result.push(strPad(time.getMonth()+1));
break;
case 'M':
// 月份的短文本表示(用三个字母表示)
result.push(dateString[1]);
break;
case 'n':
// 月份的数字表示,不带前导零(1 到 12)
result.push(strPad(time.getMonth()+1));
break;
case 't':
// 给定月份中包含的天数
temp = new Date(time);// 防止改变原时间对象
temp.setMonth(time.getMonth()+1);
temp.setDate(0);// 设置为0,date会自动切为上一个月的最后一天
result.push(temp.getDate());
break;
case 'L':
// 是否是闰年(如果是闰年则为 1,否则为 0)
temp = time.getFullYear();
if(temp%4 == 0 && temp%100 != 0 || temp%400 == 0){
result.push(1);
}else{
result.push(0);
}
break;
case 'o':
// ISO-8601 标准下的年份数字
case 'Y':
// 年份的四位数表示
result.push(time.getFullYear());
break;
case 'y':
// 年份的两位数表示
result.push(time.getFullYear().toString().substr(2,2));
break;
case 'a':
//小写形式表示:am 或 pm
temp = time.getHours();
result.push(temp<12?'am':'pm');
break;
case 'A':
// 大写形式表示:AM 或 PM
temp = time.getHours();
result.push(temp<12?'AM':'PM');
break;
// case 'B':
// // Swatch Internet Time(000 到 999)
// break;
case 'g':
// 12 小时制,不带前导零(1 到 12)
temp = time.getHours();
result.push(temp>12?temp-12:temp);