节流函数
使用 setTimeout 实现节流
/**
* @param {Function} fn 节流函数需要执行的方法
* @param {Number} timeout 需要等待的间隔 默认为 300ms
* @return: void
*/
function throttle(fn,timeout = 300){
// 使用闭包,为了防止全局污染
let timer
return function () {
let self = this
// 保存一份参数
let args = arguments
if (timer) {
clearTimeout(timer)
timer = null
}
timer = setTimeout(() => {
// 使用 call 传递参数 arguments 是个伪数组
fn.call(self, ...args)
clearTimeout(timer)
}, timeout);
}
}
window.onclick = throttle(function (e) {
console.log(e)
}, 500)
使用时间戳判断
// TODO: 这个方法有问题。
// 执行效果为 如果一直触发,那么只会每隔 timeout 执行一次
// 间隔触发,则只会执行第一触发的fn
/**
* @param {Function} fn 节流函数需要执行的方法
* @param {Number} timeout 需要等待的间隔 默认为 300ms
* @return: void
*/
function throttle(fn,timeout = 300){
// 使用闭包,为了防止全局污染
let timer = 0
return function () {
let self = this
// 保存一份参数
let args = arguments
let currentTime = new Date().valueOf()
// 如果当前时间 - 上一次时间 大于 等待时间 那么就意味着需要执行这个方法
if (currentTime - timer > timeout) {
// 使用 call 传递参数 arguments 是个伪数组
fn.call(self, ...args)
timer = currentTime
}
}
}
window.onclick = throttle(function (e) {
console.log(e)
}, 500)
数字转千分位
/**
* @params { String | Number } 需要转换为数字或者字符串数字
* @return { String } 返回处理过后的字符串。如果是非数字格式的字符串或数字则返回本身
*/
toThousands (num) {
let disposeNum = Number(num)
if (!isNaN(disposeNum) && disposeNum < 1000) return num
let re = /\d{1,3}(?=(\d{3})+$)/g
return String(num).replace(/^(\d+)((\.\d+)?)$/, (s, s1, s2) => {
return s1.replace(re, '$&,') + s2
})
}
通过流下载文件
/**
* @params { file } 需要下载的文件
* @params { fileName } 下载的文件的文件名。如果未设置,则使用文件本身的名字
* @return: void
*/
exportFile (file, fileName) {
if (!file) return undefined
// URL.createObjectURL 方法会创建一个DOMString,其中包含用其参数创建的一个 file 对象的 URL
// 也就是说 这个 URL 指向的就是 file
let url = window.URL.createObjectURL(new Blob([file]))
let link = document.createElement('a')
link.href = url
link.style.display = 'none'
if (fileName) {
// 设置文件名。有兼容问题
link.setAttribute('download', fileName)
}
document.body.appendChild(link)
link.click()
window.URL.revokeObjectURL(url)
document.body.contains(link) && document.body.removeChild(link)
}
判断是否为移动端
const isMobileBrowser = !!(navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))
基于lodash 判断当前值是否存在某个对象内部
import { isArray, isEqual, isNull, isObject, isUndefined } from 'lodash'
/**
* 判断当前值是否存在对象中
* @param value 值
* @param object 判断的值
* @param compareEmpty 是否需要对比空
*/
export const containsValue = <T extends Obj>(value: unknown, object: T, compareEmpty = false): boolean => {
if (compareEmpty) {
if (isUndefined(value) || isNull(object)) return isUndefined(object) || isNull(object)
}
if ((isArray(value) || isObject(value)) && isEqual(value, object)) return true
if (isArray(object)) {
// 数组遍历
for (let i = 0; i < object.length; i++) {
const isFind = containsValue(value, object[i])
if (isFind) return true
}
} else if (isObject(object)) {
for (const key in object) {
if (object.hasOwnProperty(key) && key !== 'constructor') {
const isFind = containsValue(value, object[key])
if (isFind) return true
}
}
} else {
return value === object
}
return false
}