工具函数


2019-9-11 拓展

判断当前终端是否PC

export const isPC = () => {
  const userAgentInfo = navigator.userAgent;
  const Agents = ['Android', 'webOS', 'BlackBerry', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'];
  let bool = true;
  for (let i = 0; i < Agents.length; i++) {
      if (userAgentInfo.indexOf(Agents[i]) > 0) {
      bool = false;
      break;
      }
  }
  return bool;
};
1
2
3
4
5
6
7
8
9
10
11
12

判断当前设备平台

export const isPlatform = () => {
  const ua = window.navigator.userAgent.toLocaleLowerCase();
  const isIOS = /iphone|ipad|ipod/.test(ua);
  const isAndroid = /android/.test(ua);
  return {
    isIOS,
    isAndroid,
  };
};
1
2
3
4
5
6
7
8
9

判断当前浏览器类型

export const isBrowser = () => {
  let [isIE, isFirefox, isChrome, isOpera, isSafari] = [0, 0, 0, 0, 0];
  if (window.ActiveXObject) {
    isIE = 1;
  }
  if (document.getBoxObjectFor) {
    isFirefox = 1;
  }
  if (window.MessageEvent && !document.getBoxObjectFor) {
    isChrome = 1;
  }
  if (window.opera) {
    isOpera = 1;
  }
  if (window.openDatabase) {
    isSafari = 1;
  }
  return {
    isIE,
    isChrome,
    isFirefox,
    isOpera,
    isSafari,
  };
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

获取浏览器版本信息

export const getBrowserInfo = () => {
  const ua = navigator.userAgent;
  const ret = {};
  const webkit = ua.match(/WebKit\/([\d.]+)/);
  const chrome = ua.match(/Chrome\/([\d.]+)/)
    || ua.match(/CriOS\/([\d.]+)/);

  const ie = ua.match(/MSIE\s([\d\.]+)/)
    || ua.match(/(?:trident)(?:.*rv:([\w.]+))?/i);
  const firefox = ua.match(/Firefox\/([\d.]+)/);
  const safari = ua.match(/Safari\/([\d.]+)/);
  const opera = ua.match(/OPR\/([\d.]+)/);

  if (webkit) {
    ret.webkit = webkit[1];
  }
  if (chrome) {
    ret.chrome = chrome[1];
  }
  if (ie) {
    ret.ie = ie[1];
  }
  if (firefox) {
    ret.firefox = firefox[1];
  }
  if (safari) {
    ret.safari = safari[1];
  }
  if (opera) {
    ret.opera = opera[1];
  }
  return ret;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

判断是否IphoneX

export const isIphonex = () => {
  if (typeof window !== 'undefined' && window) {
    return /iphone/gi.test(window.navigator.userAgent) && window.screen.height >= 812;
  }
  return false;
};
1
2
3
4
5
6

移动端键盘适配方案

/**
 * 监听输入框的软键盘弹起和收起事件
 * @param {*} $input
 */
export const listenKeyboard = ($input) => {
  const { isIOS, isAndroid } = isPlatform();
  if (isIOS) {
    $input.addEventListener('focus', () => {
      // console.log('IOS 键盘弹起');
    }, false);

    // IOS 键盘收起:IOS 点击输入框以外区域或点击收起按钮,输入框都会失去焦点,键盘会收起
    $input.addEventListener('blur', () => {
      // console.log('IOS 键盘收起');
      // 微信浏览器版本6.7.4+IOS12会出现键盘收起后,视图被顶上去了没有下来
      const wechatInfo = window.navigator.userAgent.match(/MicroMessenger\/([\d\.]+)/i);
      if (!wechatInfo) return;

      const wechatVersion = wechatInfo[1];
      const version = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);

      if (+wechatVersion.replace(/\./g, '') >= 674 && +version[1] >= 12) {
        setTimeout(() => {
          window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));
        });
      }
    }, false);
  }

  // Andriod 键盘收起:Andriod 键盘弹起或收起页面高度会发生变化,以此为依据获知键盘收起
  if (isAndroid) {
    let originHeight = document.documentElement.clientHeight || document.body.clientHeight;

    window.addEventListener('resize', () => {
      const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
      if (originHeight < resizeHeight) {
        // console.log('android 键盘收起了');
      } else {
        // console.log('android 键盘弹起了');
      }
      originHeight = resizeHeight;
    }, false);
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

安卓滚动问题

/**
 * 安卓获取到焦点元素滚动到可视区
 * @param {*} activeElement
 * @param {*} delay
 */
export const activeElementScrollIntoView = (activeElement, delay) => {
  const editable = activeElement.getAttribute('contenteditable');

  // 输入框、textarea或富文本获取焦点后没有将该元素滚动到可视区
  if (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || editable === '' || editable) {
    setTimeout(() => {
      activeElement.scrollIntoView();
    }, delay);
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

mint-ui的popup滑动穿透问题

export const touchController = (bool, $el) => {
  if (bool) {
    $el.addEventListener('touchmove', e => e.preventDefault(), { passive: false });
  } else {
    $el.removeEventListener('touchmove', e => e.preventDefault(), { passive: false });
  }
};
1
2
3
4
5
6
7

图片转base64

    <input type="file" class="file" @change="imgBroadcastChange" />

    imgBroadcastChange(e){
      if (e && e.target.files[0]) {
      const imgFile = e.target.files[0];
      if (!/image\/\w+/.test(imgFile.type)) {
        showToast('请确保文件为图像类型');
        return;
      }
      uploadImgToBase64(imgFile);
    }
  }
  // 转base64
  static uploadImgToBase64(file) {
    const size = (file.size / 1024) / 1024;
    // if (size > 2) {
    //   showToast('图片太大,超过2M');
    //   return false;
    // }
    return (new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      // 图片转base64完成后返回reader对象
      reader.onload = () => {
        resolve(reader);
        showToast('发送成功');
      };
      reader.onerror = () => {
        reject(reader);
      };
    }));
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

图片压缩


const compressImage = (file, success, error) => {
  // 图片小于1M不压缩
  if (file.size < Math.pow(1024, 2)) {
    return success(file);
  }
  // gif图片不压缩
  if (file.type === 'image/gif') {
    return success(file);
  }

  const name = file.name; //文件名
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = (e) => {
    const src = e.target.result;

    const img = new Image();
    img.src = src;
    img.onload = (e) => {
      const w = img.width;
      const h = img.height;
      const quality = 0.92;  // 默认图片质量为0.92
      //生成canvas
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      // 创建属性节点
      const anw = document.createAttribute("width");
      anw.nodeValue = w;
      const anh = document.createAttribute("height");
      anh.nodeValue = h;
      canvas.setAttributeNode(anw);
      canvas.setAttributeNode(anh);

      //铺底色 PNG转JPEG时透明区域会变黑色
      ctx.fillStyle = "#fff";
      ctx.fillRect(0, 0, w, h);

      ctx.drawImage(img, 0, 0, w, h);
      // quality值越小,所绘制出的图像越模糊
      const base64 = canvas.toDataURL('image/jpeg', quality); //图片格式jpeg或webp可以选0-1质量区间

      // 返回base64转blob的值
      console.log(`原图${(src.length / 1024).toFixed(2)}kb`, `新图${(base64.length / 1024).toFixed(2)}kb`);
      //去掉url的头,并转换为byte
      const bytes = window.atob(base64.split(',')[1]);
      //处理异常,将ascii码小于0的转换为大于0
      const ab = new ArrayBuffer(bytes.length);
      const ia = new Uint8Array(ab);
      for (let i = 0; i < bytes.length; i++) {
        ia[i] = bytes.charCodeAt(i);
      }
      file = new Blob([ab], { type: 'image/jpeg' });
      file.name = name;

      success(file);
    }
    img.onerror = (e) => {
      error(e);
    }
  }
  reader.onerror = (e) => {
    error(e);
  }
}

export default compressImage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

绑定事件

  /**
   * @description 绑定事件 on(element, event, handler)
   */
  static on = (() => {
    if (document.addEventListener) {
      return (element, event, handler) => {
        if (element && event && handler) {
          element.addEventListener(event, handler, false);
        }
      };
    }
    return (element, event, handler) => {
      if (element && event && handler) {
        element.attachEvent(`on${event}`, handler);
      }
    };
  })();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

解绑事件

  /**
   * @description 解绑事件 off(element, event, handler)
   */
  static off = (() => {
    if (document.removeEventListener) {
      return (element, event, handler) => {
        if (element && event) {
          element.removeEventListener(event, handler, false);
        }
      };
    }
    return (element, event, handler) => {
      if (element && event) {
        element.detachEvent(`on${event}`, handler);
      }
    };
  })();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

平滑的滚动

  static scrollTop = (el, from = 0, to, duration = 500, endCallback) => {
    const animateFun = callback => window.setTimeout(callback, 1000 / 60);

    if (!window.requestAnimationFrame) {
      window.requestAnimationFrame = (
        window.webkitRequestAnimationFrame
        || window.mozRequestAnimationFrame
        || window.msRequestAnimationFrame
        || animateFun
      );
    }
    const difference = Math.abs(from - to);
    const step = Math.ceil(difference / duration * 50);

    const scroll = (start, end) => {
      if (start === end) {
        if (endCallback) {
          endCallback();
        }
        return;
      }

      let d = (start + step > end) ? end : start + step;
      if (start > end) {
        d = (start - step < end) ? end : start - step;
      }

      if (el === window) {
        window.scrollTo(d, d);
      } else {
        el.scrollTop = d;
      }
      window.requestAnimationFrame(() => scroll(d, end, step));
    };
    scroll(from, to, step);
  };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

生成时间表

// 随机时间间隔(秒)
const _interval = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1) + min);
}

// 合并数组
const _flatten = (arr) => {
  return arr.reduce(function (flat, toFlatten) {
    return flat.concat(Array.isArray(toFlatten) ? _flatten(toFlatten) : toFlatten);
  }, []);
}

// 获取时间表
const _getSchedule = (startTime, endTime, startInterval, endInterval) => {
  var times = [];
  var time = startTime;
  while (time > endTime) {
    let betTime = _interval(startInterval, endInterval);
    time -= betTime;
    times.push(time)
    if (time <= endInterval) {
      break;
    }
  }
  return times;
}

// 生成时间表
const _makeTimeSchedule = (duration, currentTime, rate) => {
  let objs = [];
  let proportion = 0;
  let time = duration;
  rate.forEach((item, index) => {
    proportion += (item.rate / 100);
    objs.push(_getSchedule(time,
      time - (time * proportion),
      item.min, item.max));
    time = objs[index][objs[index].length - 1]
  })
  return _flatten(objs).filter((x) => {
    return x < currentTime;
  });;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

QS转换query参数

// 将{id: 1, token: 123}转换成id=1&token=123这种格式
const.getQueryParams = (obj) => {
  return qs.stringify(obj);
}

// 将id=1&token=123转换成{id: 1, token: 123}这种格式
const.getQueryObj = (str) => {
  return qs.parse(str);
}
1
2
3
4
5
6
7
8
9

获取粘贴板图片数据

 const pasteSendImg = (e, success) => {
    e = e || event;
    if (e.originalEvent) {
      e = e.originalEvent;
    }
    const cbd = e.clipboardData;
    const ua = window.navigator.userAgent;
    // 如果是 Safari 直接 return
    if (!(e.clipboardData && e.clipboardData.items)) {
      return;
    }
    // Mac平台下Chrome49版本以下 复制Finder中的文件的Bug Hack掉
    if (cbd.items && cbd.items.length === 2 && cbd.items[0].kind === 'string' && cbd.items[1].kind === 'file'
      && cbd.types && cbd.types.length === 2 && cbd.types[0] === 'text/plain' && cbd.types[1] === 'Files'
      && ua.match(/Macintosh/i) && Number(ua.match(/Chrome\/(\d{2})/i)[1]) < 49) {
      return;
    }
    //文件类型是Files,并且数据格式是image,才进行正常发送
    if (cbd.types[0] === 'Files' && cbd.items[0].type.indexOf('image') >= 0) {
      for (let i = 0; i < cbd.items.length; i++) {
        const item = cbd.items[i];
        if (item.kind === 'file') {
          const blob = item.getAsFile();
          if (blob.size === 0) {
            return;
          }
          success(blob);
          // blob 就是从剪切板获得的文件 可以进行上传或其他操作
        }
      }
    }
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

根据区间随机数

  /**
   * 根据区间随机数
   */
  static randomNumber = (min, max) => Math.floor(Math.random() * (max - min) + min);
1
2
3
4

通过JSON实现深拷贝(会忽略掉函数)

static deepclone = (target, origin)=> {
    target = JSON.parse(JSON.stringify(origin));
    return target;
}
1
2
3
4

获取滚动条距顶部的距离

/**
 * 
 * @desc 获取滚动条距顶部的距离
 */
function getScrollTop() {
    return (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
}
module.exports = getScrollTop;
1
2
3
4
5
6
7
8

设置滚动条距顶部的距离

  
/**
 * 
 * @desc 设置滚动条距顶部的距离
 * @param {Number} value
 */
function setScrollTop(value) {
    window.scrollTo(0, value);
    return value;
}

module.exports = setScrollTop;
1
2
3
4
5
6
7
8
9
10
11
12

获取一个元素的距离文档(document)的位置,类似jQ中的offset()

/**
 * 
 * @desc  获取一个元素的距离文档(document)的位置,类似jQ中的offset()
 * @param {HTMLElement} ele 
 * @returns { {left: number, top: number} }
 */
function offset(ele) {
    var pos = {
        left: 0,
        top: 0
    };
    while (ele) {
        pos.left += ele.offsetLeft;
        pos.top += ele.offsetTop;
        ele = ele.offsetParent;
    };
    return pos;
}

module.exports = offset;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

在${duration}时间内,滚动条平滑滚动到${to}指定位置

这里用到上面的getScrollTop和setScrollTop

var getScrollTop = require('./getScrollTop');
var setScrollTop = require('./setScrollTop');
var requestAnimFrame = (function () {
    return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        function (callback) {
            window.setTimeout(callback, 1000 / 60);
        };
})();
/**
 * 
 * @desc  在${duration}时间内,滚动条平滑滚动到${to}指定位置
 * @param {Number} to 
 * @param {Number} duration 
 */
function scrollTo(to, duration) {
    if (duration < 0) {
        setScrollTop(to);
        return
    }
    var diff = to - getScrollTop();
    if (diff === 0) return
    var step = diff / duration * 10;
    requestAnimFrame(
        function () {
            if (Math.abs(step) > Math.abs(diff)) {
                setScrollTop(getScrollTop() + diff);
                return;
            }
            setScrollTop(getScrollTop() + step);
            if (diff > 0 && getScrollTop() >= to || diff < 0 && getScrollTop() <= to) {
                return;
            }
            scrollTo(to, duration - 16);
        });
}

module.exports = scrollTo;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

H5软键盘缩回、弹起回调

/**
 * 
 * @desc H5软键盘缩回、弹起回调
 * 当软件键盘弹起会改变当前 window.innerHeight,监听这个值变化
 * @param {Function} downCb 当软键盘弹起后,缩回的回调
 * @param {Function} upCb 当软键盘弹起的回调
 */

function windowResize(downCb, upCb) {
	var clientHeight = window.innerHeight;
	downCb = typeof downCb === 'function' ? downCb : function () {}
	upCb = typeof upCb === 'function' ? upCb : function () {}
	window.addEventListener('resize', () => {
		var height = window.innerHeight;
		if (height === clientHeight) {
			downCb();
		}
		if (height < clientHeight) {
			upCb();
		}
	});
}

module.exports = windowResize;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

函数节流。

/**
 * 函数节流
 * @param {*} fn 
 * @param {*} gaptime 
 */
function throttle(fn, gaptime) {
    var timer;
    var last;
    return function() {
        var now = +new Date();
        var context = this;
        var args = arguments;
        if(last && now < last + gaptime) {
            clearTimeout(timer);
            timer = setTimeout(function(){
                last = now;
                fn.apply(context, args);
            }, gaptime)
        }else {
            last = now;
            fn.apply(context, args);
        }
    }
}
var fn = function(){
    console.log('hello' + new Date())
}
setInterval(throttle(fn, 2000), 1000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

函数防抖

/* 事件停止被触发N秒后才会再次触发回调
 * @param {Function} func - 回调执行函数
 * @param {String} wait - 触发间隔
 * @param {Boolean} immediate - 是否延时执行
 */
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

// Usage
var myEfficientFn = debounce(function() {
    // todo
}, 250);
window.addEventListener('resize', myEfficientFn);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

判读对象Obj是否为空

  
/**
 * 
 * @desc   判断`obj`是否为空
 * @param  {Object} obj
 * @return {Boolean}
 */
function isEmptyObject(obj) {
    if (!obj || typeof obj !== 'object' || Array.isArray(obj))
        return false
    return !Object.keys(obj).length
}

module.exports = isEmptyObject
1
2
3
4
5
6
7
8
9
10
11
12
13
14

随机生成颜色

/**
 * 
 * @desc 随机生成颜色
 * @return {String} 
 */
function randomColor() {
    return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);
}

module.exports = randomColor;
1
2
3
4
5
6
7
8
9
10

判断是否为邮箱地址

/**
 * 
 * @desc   判断是否为邮箱地址
 * @param  {String}  str
 * @return {Boolean} 
 */
function isEmail(str) {
    return /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(str);
}

module.exports = isEmail;
1
2
3
4
5
6
7
8
9
10
11

判断是否为身份证号

  
/**
 * 
 * @desc  判断是否为身份证号
 * @param  {String|Number} str 
 * @return {Boolean}
 */
function isIdCard(str) {
    return /^(^[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])$)$/.test(str)
}

module.exports = isIdCard
1
2
3
4
5
6
7
8
9
10
11
12

判断是否为手机号

/**
 * 
 * @desc   判断是否为手机号
 * @param  {String|Number} str 
 * @return {Boolean} 
 */
function isPhoneNum(str) {
    return /^(\+?0?86\-?)?1[3456789]\d{9}$/.test(str)
}

module.exports = isPhoneNum
1
2
3
4
5
6
7
8
9
10
11

判读url地址是否有效

/**
 * 
 * @desc   判断是否为URL地址
 * @param  {String} str 
 * @return {Boolean}
 */
function isUrl(str) {
    return /[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/i.test(str);
}

module.exports = isUrl;
1
2
3
4
5
6
7
8
9
10
11

现金额转大写

/**
 * 
 * @desc   现金额转大写
 * @param  {Number} n 
 * @return {String}
 */
function digitUppercase(n) {
    var fraction = ['角', '分'];
    var digit = [
        '零', '壹', '贰', '叁', '肆',
        '伍', '陆', '柒', '捌', '玖'
    ];
    var unit = [
        ['元', '万', '亿'],
        ['', '拾', '佰', '仟']
    ];
    var head = n < 0 ? '欠' : '';
    n = Math.abs(n);
    var s = '';
    for (var i = 0; i < fraction.length; i++) {
        s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');
    }
    s = s || '整';
    n = Math.floor(n);
    for (var i = 0; i < unit[0].length && n > 0; i++) {
        var p = '';
        for (var j = 0; j < unit[1].length && n > 0; j++) {
            p = digit[n % 10] + unit[1][j] + p;
            n = Math.floor(n / 10);
        }
        s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
    }
    return head + s.replace(/(零.)*零元/, '元')
        .replace(/(零.)+/g, '零')
        .replace(/^整$/, '零元整');
};

module.exports = digitUppercase
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

判断浏览器是否支持webP格式图片

/**
 * 
 * @desc 判断浏览器是否支持webP格式图片
 * @return {Boolean} 
 */
function isSupportWebP() {
    return !![].map && document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0;
}

module.exports = isSupportWebP;
1
2
3
4
5
6
7
8
9
10

格式化${startTime}距现在的已过时间

/**
 * @desc   格式化${startTime}距现在的已过时间
 * @param  {Date} startTime 
 * @return {String}
 */
function formatPassTime(startTime) {
    var currentTime = Date.parse(new Date()),
        time = currentTime - startTime,
        day = parseInt(time / (1000 * 60 * 60 * 24)),
        hour = parseInt(time / (1000 * 60 * 60)),
        min = parseInt(time / (1000 * 60)),
        month = parseInt(day / 30),
        year = parseInt(month / 12);
    if (year) return year + "年前"
    if (month) return month + "个月前"
    if (day) return day + "天前"
    if (hour) return hour + "小时前"
    if (min) return min + "分钟前"
    else return '刚刚'
}

module.exports = formatPassTime
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

格式化现在距${endTime}的剩余时间

/**
 * @desc   格式化现在距${endTime}的剩余时间
 * @param  {Date} endTime  
 * @return {String}
 */
function formatRemainTime(endTime) {
    var startDate = new Date(); //开始时间
    var endDate = new Date(endTime); //结束时间
    var t = endDate.getTime() - startDate.getTime(); //时间差
    var d = 0,
        h = 0,
        m = 0,
        s = 0;
    if (t >= 0) {
        d = Math.floor(t / 1000 / 3600 / 24);
        h = Math.floor(t / 1000 / 60 / 60 % 24);
        m = Math.floor(t / 1000 / 60 % 60);
        s = Math.floor(t / 1000 % 60);
    }
    return d + "天 " + h + "小时 " + m + "分钟 " + s + "秒";
}
module.exports = formatRemainTime
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

判断是否为闰年

/**
 * @desc 是否为闰年
 * @param {Number} year
 * @returns {Boolean}
 */

function isLeapYear(year) {
  if (0 === year % 4 && (year % 100 !== 0 || year % 400 === 0)) {
    return true
  }
  return false;
}

module.exports = isLeapYear;
1
2
3
4
5
6
7
8
9
10
11
12
13
14

判断是否为同一天

/**
 * @desc   判断是否为同一天
 * @param  {Date} date1 
 * @param  {Date} date2 可选/默认值:当天
 * @return {Boolean}
 */
function isSameDay(date1, date2) {
    if (!date2) {
        date2 = new Date();
    }
    var date1_year = date1.getFullYear(),
        date1_month = date1.getMonth() + 1,
        date1_date = date1.getDate();
    var date2_year = date2.getFullYear(),
        date2_month = date2.getMonth() + 1,
        date2_date = date2.getDate()

    return date1_date === date2_date && date1_month === date2_month && date1_year === date2_year;

}
module.exports = isSameDay
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

url参数转对象

/**
 * @desc   url参数转对象
 * @param  {String} url  default: window.location.href
 * @return {Object} 
 */
function parseQueryString(url) {
    url = !url ? window.location.href : url;
    if(url.indexOf('?') === -1) {
        return {};
    }
    var search = url[0] === '?' ? url.substr(1) : url.substring(url.lastIndexOf('?') + 1);
    if (search === '') {
        return {};
    }
    search = search.split('&');
    var query = {};
    for (var i = 0; i < search.length; i++) {
        var pair = search[i].split('=');
        query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
    }
    return query;
}
module.exports = parseQueryString
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

获取操作系统类型

function getOS() {
    var userAgent = 'navigator' in window && 'userAgent' in navigator && navigator.userAgent.toLowerCase() || '';
    var vendor = 'navigator' in window && 'vendor' in navigator && navigator.vendor.toLowerCase() || '';
    var appVersion = 'navigator' in window && 'appVersion' in navigator && navigator.appVersion.toLowerCase() || '';

    if (/iphone/i.test(userAgent) || /ipad/i.test(userAgent) || /ipod/i.test(userAgent)) return 'ios'
    if (/android/i.test(userAgent)) return 'android'
    if (/win/i.test(appVersion) && /phone/i.test(userAgent)) return 'windowsPhone'
    if (/mac/i.test(appVersion)) return 'MacOSX'
    if (/win/i.test(appVersion)) return 'windows'
    if (/linux/i.test(appVersion)) return 'linux'
}

module.exports = getOS;
1
2
3
4
5
6
7
8
9
10
11
12
13
14

once

实用的执行一次函数,不用多解释。虽然很简单的函数,但是防止重复加载或者初始化的习惯必须养成。

function once(fn, context) { 
    var result;

    return function() { 
        if(fn) {
            result = fn.apply(context || this, arguments);
            fn = null;
        }

        return result;
    };
}

// Usage
var canOnlyFireOnce = once(function() {
    console.log('Fired!');
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

poll

很多时候,我们需要了解某个函数的执行状态,并根据状态执行相应的处理。在没有事件通知时,需要以一定的时间间隔轮询执行状态。

/* 轮询条件函数,根据状态执行相应回调
 * @param {Function} fn- 条件函数
 * @param {Function} callback - 成功回调
 * @param {Function} errback - 失败回调
 * @param {int} timeout - 超时间隔
 * @param {int} interval - 轮询间隔
 */
function poll(fn, callback, errback, timeout, interval) {
    var endTime = Number(new Date()) + (timeout || 2000);
    interval = interval || 100;

    (function p() {
            // If the condition is met, we're done! 
            if(fn()) {
                callback();
            }
            // If the condition isn't met but the timeout hasn't elapsed, go again
            else if (Number(new Date()) < endTime) {
                setTimeout(p, interval);
            }
            // Didn't match and too much time, reject!
            else {
                errback(new Error('timed out for ' + fn + ': ' + arguments));
            }
    })();
}

// Usage:  ensure element is visible
poll(
    function() {
        return document.getElementById('lightbox').offsetWidth > 0;
    },
    function() {
        // Done, success callback
    },
    function() {
        // Error, failure callback
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

将一个多维数组进行组合,返回一个新数组

     function doExchange(doubleArrays) {
        var len = doubleArrays.length;
        if (len >= 2) {
            var len1 = doubleArrays[0].length;
            var len2 = doubleArrays[1].length;
            var newlen = len1 * len2;
            var temp = new Array(newlen);
            var index = 0;
            for (var i = 0; i < len1; i++) {
                for (var j = 0; j < len2; j++) {
                    temp[index] = doubleArrays[0][i] +
                        doubleArrays[1][j];
                    index++;
                }
            }
            var newArray = new Array(len - 1);
            for (var i = 2; i < len; i++) {
                newArray[i - 1] = doubleArrays[i];
            }
            newArray[0] = temp;
            console.log(newArray)
            return doExchange(newArray);
        }
        else {
            return doubleArrays[0];
        }
    }
    var temparr = [
            ["0", "1", "2"],
            ["3", "4"],
            ['5','6']
            ];
    var ret = doExchange(temparr);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

pc端新开窗口弹窗

const popupWindow = (url, type, w, h) => {
  const left = (window.screen.width / 2) - (w / 2);
  const top = (window.screen.height / 2) - (h / 2);
  return window.open(url, type, `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${w}, height=${h}, top=${top}, left=${left}`);
};
1
2
3
4
5

兼容所有浏览器的获取样式的函数

function  getstyle(obj,name){

   if(window.getComputedStyle){

           return getComputedStyle(obj,null)[name];

   }else{

          return obj.currentStyle[name];

     }

}
1
2
3
4
5
6
7
8
9
10
11
12
13

特别鸣谢:YIXIU;

Thomas: 11/8/2019, 7:21:50 PM