/** * @description 防抖 * @param {Function} func 需要包装的函数 * @param {string} wait 等待执行时间 * @param {boolean} immediate 是否是立即执行 默认不立即执行 * @returns {Function} 返回包装后的函数 */ export function debounce(func, wait, immediate = true) { let timeout, result return function() { const context = this const args = arguments if (timeout) clearTimeout(timeout) if (immediate) { const callNow = !timeout timeout = setTimeout(function() { timeout = null }, wait) if (callNow) result = func.apply(context, args) } else { timeout = setTimeout(function() { func.apply(context, args) }, wait) } return result } } /** * @description 节流 * @param {Function} func 需要包装的函数 * @param {string} wait 间隔时间 * @returns {Function} 返回包装后的函数 */ export function throttle(func, wait) { let timeout return function() { const context = this const args = arguments if (!timeout) { timeout = setTimeout(function() { timeout = null func.apply(context, args) }, wait) } } } /** * @description 深度克隆 * @param {object} obj 克隆目标 * @returns {object} 返回目标对象深度克隆后的结果 */ export function deepClone(obj, cache = new WeakMap()) { if (typeof obj !== 'object') return obj // 普通类型,直接返回 if (obj === null) return obj if (cache.get(obj)) return cache.get(obj) // 防止循环引用,程序进入死循环 if (obj instanceof Date) return new Date(obj) if (obj instanceof RegExp) return new RegExp(obj) // 找到所属原型上的constructor,所属原型上的constructor指向当前对象的构造函数 let cloneObj = new obj.constructor() cache.set(obj, cloneObj) // 缓存拷贝的对象,用于处理循环引用的情况 for (let key in obj) { if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key], cache) // 递归拷贝 } } return cloneObj } /** * @description 时间日期格式化 * @param {dateTime} date 标准时间格式 -> new Date() * @param {string} format 时间格式化的格式 'yyyy-MM-dd hh:mm:ss' * @returns {string} 格式化后的时间 '2017-01-01 01:00:00' */ export function dateFormat(date = new Date(), format = 'yyyy-MM-dd hh:mm:ss') { var o = { 'M+': date.getMonth() + 1, // month 'd+': date.getDate(), // day 'h+': date.getHours(), // hour 'm+': date.getMinutes(), // minute 's+': date.getSeconds(), // second 'q+': Math.floor((date.getMonth() + 3) / 3), // quarter S: date.getMilliseconds(), // millisecond } if (/(y+)/.test(format)) { format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)) } for (var k in o) { if (new RegExp('(' + k + ')').test(format)) { format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]) .length)) } } return format } /** * @description 倒计时 * @param diff 倒计时时间(s) * @param loadTime 运行时的当前时间(s) * @param item 倒计时对象 默认:{ speed: 1000 } * @param callback 回调 */ export function countDown(diff, loadTime, item, callback) { function round($diff) { let dd = parseInt($diff / 1000 / 60 / 60 / 24, 10) // 计算剩余的天数 let hh = parseInt(($diff / 1000 / 60 / 60) % 24, 10) // 计算剩余的小时数 let mm = parseInt(($diff / 1000 / 60) % 60, 10) // 计算剩余的分钟数 let ss = parseInt(($diff / 1000) % 60, 10) // 计算剩余的秒数 function checkTime(_a) { let a = _a if (a < 10) { a = '0' + a } return a.toString() } item.conttainer = { ddhh: checkTime(dd * 24 + hh), dd: checkTime(dd), hh: checkTime(hh), mm: checkTime(mm), ss: checkTime(ss) } if ( item.conttainer.dd > 0 || item.conttainer.hh > 0 || item.conttainer.mm > 0 || item.conttainer.ss > 0 ) { item.t = setTimeout(function() { round($diff - (item.speed || 1000)) }, item.speed || 1000) } // 回调 callback && callback(item) } round(diff - loadTime) } /* 对象循环赋值 */ export function objAssign(target = {}, source = {}) { for (let key in target) { if (source.hasOwnProperty(key)) { target[key] = source[key] } } } /* 数组去重 */ export function arrayUnique(arr) { if (!Array.isArray(arr)) { console.log('type error!') return } return Array.from(new Set(arr)) } /* * 反序列化URL参数 * { age: "25", name: "Tom" } */ export function parseUrlSearch(location) { return location.search .replace(/(^\?)|(&$)/g, '') .split('&') .reduce((t, v) => { const [key, val] = v.split('=') t[key] = decodeURIComponent(val) return t }, {}) } /* * getQueryParams('id') * 获取url上某个key的值 */ export function getParam(param) { // 获取浏览器参数 const r = new RegExp(`\\?(?:.+&)?${param}=(.*?)(?:&.*)?$`) const m = window.location.toString().match(r) return m ? decodeURI(m[1]) : '' } /* * queryStringify * 将k-v的对象序列化转成 url?k=v&k1=v1; */ export function queryStringify(search = {}) { return Object.entries(search) .reduce((t, v) => `${t}${v[0]}=${encodeURIComponent(v[1])}&`, '') .replace(/&$/, '') } /* * queryStringify * 将url?k=v&k1=v1的序列化转成k-v对象 */ export function queryParse(query = '') { if (query.startsWith('?')) { query = query.slice(0) } const obj = Object.create(null) query.split('&').forEach(str => { const v = str.split('=') obj[v[0]] = v[1] }) return obj }