生成 uid

  1. /**
  2. * 生成uid
  3. *
  4. * @export
  5. * @returns
  6. */
  7. export function uid () {
  8. function s4 () {
  9. return Math.floor((1 + Math.random()) * 0x10000)
  10. .toString(16)
  11. .substring(1)
  12. }
  13. return `${s4()}${s4()}-${s4()}-${s4()}-${s4()}-${s4()}${s4()}${s4()}`
  14. }

获取地址栏参数

  1. /**
  2. * 获取地址栏参数
  3. *
  4. * @export
  5. * @param {*} url
  6. * @returns
  7. */
  8. export function getParams (url) {
  9. try {
  10. url = url.match(/\?([^#]+)/)[1]
  11. const arr = url.split('&')
  12. let obj = {}
  13. for (let i = 0; i < arr.length; i++) {
  14. const subArr = arr[i].split('=')
  15. obj[subArr[0]] = subArr[1]
  16. }
  17. return obj
  18. } catch (err) {
  19. return null
  20. }
  21. }

设置地址参数

  1. /**
  2. * 设置地址参数
  3. *
  4. * @export
  5. * @param {*} params
  6. * @returns
  7. */
  8. export function serUrlParams (url, params) {
  9. for (let k in params) {
  10. let value = params[k] !== undefined && params[k] !== null ? params[k] : ''
  11. value = encodeURIComponent(decodeURIComponent(value))
  12. url += `&${k}=${value}`
  13. }
  14. return url ? url.substring(1) : ''
  15. }

金额格式化

  1. /*
  2. * formatMoney(s,type)
  3. * 功能:金额按千位逗号分割
  4. * 参数:s,需要格式化的金额数值.
  5. * 参数:type,(number类型)金额的小数位.
  6. * 返回:返回格式化后的数值.
  7. */
  8. var formatMoney = (val, type) => {
  9. if (val === '' || val === 0) return '0.00'
  10. val = Number(val)
  11. if (isNaN(val)) return ''
  12. return val.toFixed(type).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
  13. }
  1. /**
  2. * 格式化数字
  3. *
  4. * @export
  5. * @param {*} number 需要格式化的数字
  6. * @param {number} [decimals=2] 保留几位小数,默认2位
  7. * @param {string} [decPoint='.'] 小数点符号,默认是点.
  8. * @param {string} [thousandsSep=','] 千分位符号,默认逗号,
  9. * @param {string} [roundtag='ceil'] 舍入参数,默认 "ceil" 向上取,"floor"向下取,"round" 四舍五入
  10. * @return {*}
  11. */
  12. export function formatNumber (
  13. number,
  14. decimals = 2,
  15. decPoint = '.',
  16. thousandsSep = ',',
  17. roundtag = 'ceil'
  18. ) {
  19. number = (number + '').replace(/[^0-9+-Ee.]/g, '')
  20. const n = !isFinite(+number) ? 0 : +number
  21. const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
  22. let s = ''
  23. const toFixedFix = function (n, prec) {
  24. const k = Math.pow(10, prec)
  25. return (
  26. '' +
  27. parseFloat(
  28. Math[roundtag](parseFloat((n * k).toFixed(prec * 2))).toFixed(prec * 2)
  29. ) /
  30. k
  31. )
  32. }
  33. s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
  34. const re = /(-?\d+)(\d{3})/
  35. while (re.test(s[0])) {
  36. s[0] = s[0].replace(re, '$1' + thousandsSep + '$2')
  37. }
  38. if ((s[1] || '').length < prec) {
  39. s[1] = s[1] || ''
  40. s[1] += new Array(prec - s[1].length + 1).join('0')
  41. }
  42. return s.join(decPoint)
  43. }

获取地址栏参数

  1. const getURLParameters = url =>
  2. (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
  3. (a, v) => (
  4. (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a
  5. ),
  6. {}
  7. )

深度合并对象

  1. const deepMerge = (a, b, fn) =>
  2. [...new Set([...Object.keys(a), ...Object.keys(b)])].reduce(
  3. (acc, key) => ({ ...acc, [key]: fn(key, a[key], b[key]) }),
  4. {}
  5. );
  6. // 例子
  7. deepMerge(
  8. { a: true, b: { c: [1, 2, 3] } },
  9. { a: false, b: { d: [1, 2, 3] } },
  10. (key, a, b) => (key === 'a' ? a && b : Object.assign({}, a, b))
  11. );
  12. // { a: false, b: { c: [ 1, 2, 3 ], d: [ 1, 2, 3 ] } }

深度克隆

  1. const deepClone = obj => {
  2. if (obj === null) return null
  3. let clone = Object.assign({}, obj)
  4. Object.keys(clone).forEach(
  5. key =>
  6. (clone[key] =
  7. typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
  8. )
  9. if (Array.isArray(obj)) {
  10. clone.length = obj.length
  11. return Array.from(clone)
  12. }
  13. return clone
  14. };
  15. // 例子
  16. const a = { foo: 'bar', obj: { a: 1, b: 2 } }
  17. const b = deepClone(a) // a !== b, a.obj !== b.obj

重命名键

  1. const renameKeys = (keysMap, obj) =>
  2. Object.keys(obj).reduce(
  3. (acc, key) => ({
  4. ...acc,
  5. ...{ [keysMap[key] || key]: obj[key] }
  6. }),
  7. {}
  8. );
  9. // 例子
  10. const obj = { name: 'Bobo', job: 'Front-End Master', shoeSize: 100 }
  11. renameKeys({ name: 'firstName', job: 'passion' }, obj)
  12. // { firstName: 'Bobo', passion: 'Front-End Master', shoeSize: 100 }

解析Cookie

  1. const parseCookie = str =>
  2. str
  3. .split(';')
  4. .map(v => v.split('='))
  5. .reduce((acc, v) => {
  6. acc[decodeURIComponent(v[0].trim())] = decodeURIComponent(v[1].trim());
  7. return acc;
  8. }, {});
  9. // 例子
  10. parseCookie('foo=bar; equation=E%3Dmc%5E2');
  11. // { foo: 'bar', equation: 'E=mc^2' }

序列化Form

  1. const serializeForm = form =>
  2. Array.from(new FormData(form), field =>
  3. field.map(encodeURIComponent).join('=')
  4. ).join('&');
  5. // 例子
  6. serializeForm(document.querySelector('#form'));
  7. // email=test%40email.com&name=Test%20Name

Form转Object

  1. const formToObject = form =>
  2. Array.from(new FormData(form)).reduce(
  3. (acc, [key, value]) => ({
  4. ...acc,
  5. [key]: value
  6. }),
  7. {}
  8. );
  9. // 例子
  10. formToObject(document.querySelector('#form'));
  11. // { email: 'test@email.com', name: 'Test Name' }

记录动画帧

  1. const recordAnimationFrames = (callback, autoStart = true) => {
  2. let running = false,
  3. raf;
  4. const stop = () => {
  5. if (!running) return;
  6. running = false;
  7. cancelAnimationFrame(raf);
  8. };
  9. const start = () => {
  10. if (running) return;
  11. running = true;
  12. run();
  13. };
  14. const run = () => {
  15. raf = requestAnimationFrame(() => {
  16. callback();
  17. if (running) run();
  18. });
  19. };
  20. if (autoStart) start();
  21. return { start, stop };
  22. };
  23. // 例子
  24. const cb = () => console.log('Animation frame fired');
  25. const recorder = recordAnimationFrames(cb);
  26. // logs 'Animation frame fired' on each animation frame
  27. recorder.stop(); // stops logging
  28. recorder.start(); // starts again
  29. const recorder2 = recordAnimationFrames(cb, false);
  30. // `start` needs to be explicitly called to begin recording frames

是否是浏览器环境

  1. const isBrowser = () => ![typeof window, typeof document].includes('undefined');
  2. // 例子
  3. isBrowser(); // true (browser)
  4. isBrowser(); // false (Node)

是否是绝对URL

  1. const isAbsoluteURL = str => /^[a-z][a-z0-9+.-]*:/.test(str);
  2. // 例子
  3. isAbsoluteURL('https://google.com'); // true
  4. isAbsoluteURL('ftp://www.myserver.net'); // true
  5. isAbsoluteURL('/foo/bar'); // false

平滑滚动到顶部

  1. const scrollToTop = () => {
  2. const c = document.documentElement.scrollTop || document.body.scrollTop;
  3. if (c > 0) {
  4. window.requestAnimationFrame(scrollToTop);
  5. window.scrollTo(0, c - c / 8);
  6. }
  7. };
  8. // 例子
  9. scrollToTop(); // Smooth-scrolls to the top of the page

检测当前用户的首选语言

  1. const detectLanguage = (defaultLang = 'en-US') =>
  2. navigator.language ||
  3. (Array.isArray(navigator.languages) && navigator.languages[0]) ||
  4. defaultLang;
  5. // 例子
  6. detectLanguage(); // 'zh-CN'

平滑滚动到指定元素

  1. const smoothScroll = element =>
  2. document.querySelector(element).scrollIntoView({
  3. behavior: 'smooth'
  4. });
  5. // 例子
  6. smoothScroll('#fooBar'); // scrolls smoothly to the element with the id fooBar
  7. smoothScroll('.fooBar');
  8. // scrolls smoothly to the first element with a class of fooBar

获取滚动位置

  1. const getScrollPosition = (el = window) => ({
  2. x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  3. y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
  4. });
  5. // 例子
  6. getScrollPosition(); // {x: 0, y: 200}

检测用户设备类型

  1. const detectDeviceType = () =>
  2. /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
  3. navigator.userAgent
  4. )
  5. ? 'Mobile'
  6. : 'Desktop';
  7. // 例子
  8. detectDeviceType(); // 'Mobile' or 'Desktop'

检查是否启用localStorage

  1. const isLocalStorageEnabled = () => {
  2. try {
  3. const key = `__storage__test`;
  4. window.localStorage.setItem(key, null);
  5. window.localStorage.removeItem(key);
  6. return true;
  7. } catch (e) {
  8. return false;
  9. }
  10. };
  11. // 例子
  12. isLocalStorageEnabled(); // true, if localStorage is accessible

检查是否启用sessionStorage

  1. const isSessionStorageEnabled = () => {
  2. try {
  3. const key = `__storage__test`;
  4. window.sessionStorage.setItem(key, null);
  5. window.sessionStorage.removeItem(key);
  6. return true;
  7. } catch (e) {
  8. return false;
  9. }
  10. };
  11. isSessionStorageEnabled(); // true, if sessionStorage is accessible

检查是否支持Touch事件

  1. const supportsTouchEvents = () =>
  2. window && 'ontouchstart' in window;
  3. // 例子
  4. supportsTouchEvents(); // true

检查是否见底

  1. const bottomVisible = () =>
  2. document.documentElement.clientHeight + window.scrollY >=
  3. (document.documentElement.scrollHeight ||
  4. document.documentElement.clientHeight);
  5. // 例子
  6. bottomVisible(); // true