12.常用工具函数

/****************************************** Array start ******************************************/

// 初始化数组
// Array(len).fill() === Array.from({length: len}) ????
const ArrayInitWithLen = len => Array(len).fill().map((v, i) => i++)
const ArrayInitWithRange = (start, end) => Array.from({ length: end - start }).map((v, i) => i + start)
const ArrayInitWithVal = (len, val) => Array(len).fill(val)
// 返回最大值元素
const ArrayMax = arr => Math.max(...arr)
// 返回最小值元素
const ArrayMin = arr => Math.min(...arr)
// 返回一个数字数组的总和
const ArraySum = arr => arr.reduce((acc, val) => acc + val, 0)
// 返回数字数组的平均值
const ArrayAverage = arr => ArraySum(arr)/arr.length
// 返回数字数组的中间值
const ArrayMiddle = arr => {
  let mid = Math.floor(arr.length / 2),
    nums = arr.sort((a, b) => a - b)
  return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
}

/**
 * [数组排序]
 * @param  {[type]} arr  [数组]
 * @param  {[type]} key) [key]
 * @return {[type]}      [description]
 */
const ArraySortBy = (arr, key) => arr.sort((a, b) => {
  if(key === undefined){
    return a - b
  }else if(typeof key === 'function'){
    return arr.sort(key)
  }else if(isNaN(a[key])){
    return a[key].localeCompare(b[key])
  }else{
    return a[key] - b[key]
  }
})
// 扁平化数组
const ArrayFlat = (arr, depth = Infinity) => arr.flat(depth)
// 数组去重
const ArrayDuplicate = arr => [...new Set(arr)]
// 将数组按照长度分段
const ArrayChunk = (arr, len) => Array.from({ length: Math.ceil(arr.length / len) }, (v, i) => arr.slice(i * len, i * len + len))
// 筛选出 falsey 值 ( false、 null、 0、 ''、 undefined 和 NaN )
const ArrayCompact = arr => arr.filter(Boolean)
// 返回唯一值
const ArrayUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
// 随机数组值的顺序
const ArrayShuffle = arr => arr.sort(() => Math.random() - 0.5);
// 计算元素出现的次数
const ArrayCountOccurrences = (arr, val) => arr.reduce((a, v) => v === val ? a + 1 : a, 0)
// 返回数组中每间隔第 n 个元素
const ArrayEveryNth = (arr, nth) => arr.filter((e, i) => i % nth === 0)
// 返回两个数组中都存在的元素
const ArraySimilarity = (arr1, arr2) => arr1.filter(v => arr2.includes(v))
// 返回第一个数组与第二个数组不同的元素
const ArrayDifference = (arr1, arr2) => { let s = new Set(arr2); return arr1.filter(x => !s.has(x)); }
// 返回两个数组之间的差集(差异的部分)
const ArraySymmetricDifference = (arr1, arr2) => {
  let sA = new Set(arr1),
    sB = new Set(arr2);
  return [...arr1.filter(x => !sB.has(x)), ...arr2.filter(x => !sA.has(x))]
}

/******************************************* Array end *******************************************/


/******************************************* Date start ******************************************/

// 返回两个日期之间的差异 (以天为值)
const DateGetDaysBetween = (start, end) => (start - end) / (1000 * 3600 * 24)

/******************************************* Date end ********************************************/


/****************************************** Number start *****************************************/

// 返回指定范围内的随机数, floor 是否生成整数
const NumberRandomInRange = (min, max, floor) => {
  let random = Math.random() * (max - min + floor)
  return (floor ? Math.floor(random) : random) + min
}
// 将数字四舍五入到指定的位数
const NumberRound = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`).toFixed(decimals)

/******************************************* Number end ******************************************/


/****************************************** String start *****************************************/

// 将字符串的第一个字母大写
const StringCapitalize = ([first, ...rest], lowerRest = false) => first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join(''))
// 将字符串中每个单词的首字母大写
const StringCapitalizeEvery = str => str.replace(/\b[a-z]/g, char => char.toUpperCase())
// 从匹配转换字符串(将驼峰写法转换成自定义分隔符的写法)
const StringFromCamelCase = (str, separator = '_') => str.replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2').replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2').toLowerCase();
// 将字符串转换为匹配
const StringToCamelCase = str => str.replace(/^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2, offset) => p2 ? p2.toUpperCase() : p1.toLowerCase())
// 反转字符串
const StringReverse = str => [...str].reverse().join('')
// 按字母顺序对字符串中的字符进行排序
const StringSort = str => str.split('').sort((a, b) => a.localeCompare(b)).join('')
// 将字符串截断为指定长度, 并拼接自定义字符串
const StringTruncate = (str, num, separator = '...') => str.length > num ? str.slice(0, num) + separator : str

/******************************************* String end ******************************************/



/********************************************* is start ******************************************/

const isArray = val => Array.isArray(val)
const isString = val => typeof val === 'string'
const isNumber = val => typeof val === 'number'
const isBoolean = val => typeof val === 'boolean'
const isFunction = val => typeof val === 'function'
const isSymbol = val => typeof val === 'symbol'
// 基本类型
const isStatic = type => type === null || ['string','number', 'boolean', 'undefined', 'symbol'].includes(typeof type)
// 注意: function 不是 原始类型,这里加进去是因为可以用 typeof 返回
const isUndefined = type => typeof type === 'undefined'
const isNull = type => type === null

/********************************************** is end *******************************************/


/******************************************* getType start ***************************************/

const getRef = function (obj) {
  let _type = Object.prototype.toString.call(obj).slice(8, -1)
  let map = {
    'Array': 'array',
    'Object': 'object',
    'Function': 'function',
    'Date': 'date',
    'RegExp': 'regExp'
  }
  return map[_type]
}

const getType = function (obj) {
  return obj === null ? 'null' : isStatic(obj) ? typeof obj : getRef(obj)
}

/********************************************* getType end ***************************************/


/******************************************* DOM start *******************************************/

// 如果页面的底部可见, 则返回true , 否则为false
const DomIsBottomVisible = () => document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight
// 如果指定的元素在视区中可见, 则返回true , 否则为false。 第二个参数是否完全可见
const DomIsElementInViewport = (el, partiallyVisible = false) => {
  let { top, left, bottom, right } = el.getBoundingClientRect();
  return partiallyVisible ?
    ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) :
    top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth
};
// 返回当前页的滚动位置
const DomGetScrollPosition = (el = window) => {
  return {
    x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft,
    y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop
  }
}
// 元素
const DomGetEle = el => document.querySelector(el)
const DomGetEles = el => document.querySelectorAll(el)
const DomEleToArray = el => Array.from(DomGetEles(el))
// classList
const DomGetEleClass = el => DomGetEle(el).classList
const DomEleHasClass = (el, cls) => DomGetEleClass(el).contains(cls)
const DomToggleClass = (el, cls) => DomGetEleClass(el).toggle(cls)
// 属性
const DomGetEleAttr = (el, key) => DomGetEle(el).getAttribute(key)
const DomSetEleAttr = (el, key) => DomGetEle(el).setAttribute(key)
// 位置尺寸
const DomGetEleClientRect = (el, key) => {
  let rect = DomGetEle(el).getBoundingClientRect();
  return !!key ? rect[k] : rect
}
// 这里这里还不清楚 offsetHeight 与 clientHeight 的区别
const DomGetEleOffset = (el, key) => {
  if(!!key) throw new Error('missing required options')
  return DomGetEle(el)[`offset${StringCapitalize(key)}`]
}
const DomGetEleClient = (el, key) => {
  if(!!key) throw new Error('missing required options')
  return DomGetEle(el)[`Client${StringCapitalize(key)}`]
}
// 平滑滚动到页面顶部
const DomScrollToTop = () => {
  let c = document.documentElement.scrollTop || document.body.scrollTop;
  if (c > 0) {
    window.requestAnimationFrame(DomScrollToTop);
    window.scrollTo(0, c - c / 8);
  }
}

/******************************************** DOM end ********************************************/


/******************************************* BOM start *******************************************/

// 返回当前 URL
const BomGetCurrentURL = () => window.location.href
// 返回一个包含当前 URL 参数的对象
const BomGetURLParams = url => url.match(/([^?=&]+)(=([^&]*))/g).reduce((a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {})

/******************************************** BOM end ********************************************/

exports._is = {
  string: isString,
  number: isNumber,
  boolean: isBoolean,
  _undefined: isUndefined,
  _null: isNull,
  symbol: isSymbol,
  function: isFunction,
  array: isArray,
  static: isStatic,
}

exports._type = {
  getRef: getRef,
  getType: getType,
}

exports._string = {
  capitalizeFirst: StringCapitalize,
  capitalizeEvery: StringCapitalizeEvery,
  fromCamelCase: StringFromCamelCase,
  toCamelCase: StringToCamelCase,
  reverse: StringReverse,
  sort: StringSort,
  truncate: StringTruncate
}

exports._date = {
  getDaysBetween: DateGetDaysBetween
}


exports._number = {
  randomInRange: NumberRandomInRange,
  round: NumberRound
}


exports._array = {
  initWithLen: ArrayInitWithLen,
  initWithRange: ArrayInitWithRange,
  initWithVal: ArrayInitWithVal,
  max: ArrayMax,
  min: ArrayMin,
  sum: ArraySum,
  average: ArrayAverage,
  middle: ArrayMiddle,
  sortBy: ArraySortBy,
  flat: ArrayFlat,
  duplicate: ArrayDuplicate,
  chunk: ArrayChunk,
  compact: ArrayCompact,
  unique: ArrayUnique,
  shuffle: ArrayShuffle,
  countOccurrences: ArrayCountOccurrences,
  everyNth: ArrayEveryNth,
  similarity: ArraySimilarity,
  difference: ArrayDifference,
  symmetricDifference: ArraySymmetricDifference,
}

exports._object = {
}

exports._clone = {
}

exports._dom = {
  isBottomVisible: DomIsBottomVisible,
  isElementInViewport: DomIsElementInViewport,
  getScrollPosition: DomGetScrollPosition,
  getEle: DomGetEle,
  getEles: DomGetEles,
  eleToArray: DomEleToArray,
  getClass: DomGetEleClass,
  hasClass: DomEleHasClass,
  toggleClass: DomToggleClass,
  getAttr: DomGetEleAttr,
  setAttr: DomSetEleAttr,
  getClientRect: DomGetEleClientRect,
  getOffset: DomGetEleOffset,
  getClient: DomGetEleClient,
  scrollToTop: DomScrollToTop,
}

exports._bom = {
  getCurrentURL: BomGetCurrentURL,
  getURLParams: BomGetURLParams,
}

你可能感兴趣的:(12.常用工具函数)