工具函数
封装自己常用的工具函数
休眠函数
等待 1000ms
后执行
ts
export function sleep<T>(ms: number, callback?: Function) {
return new Promise<T>((resolve, reject) =>
setTimeout(async () => {
try {
const value = await callback?.()
resolve(value)
}
catch (error) {
reject(error)
}
}, ms),
)
}
设置 rem 基准值
设计稿的尺寸375
ts
export function setRem(screen = 375) {
const docEl = document.documentElement
function setBodyFontSize() {
const scale = docEl.clientWidth / screen
docEl.style.fontSize = `${(screen / 10) * Math.min(scale, 2)}px`
}
setBodyFontSize()
window.addEventListener('resize', setBodyFontSize, false)
}
经纬度计算距离
计算结果返回km
单位
ts
/**
* 根据经纬度计算距离(km)
* @param lo1 经度
* @param la1 维度
* @param lo2 经度
* @param la2 维度
*/
export function computeDistance(lo1: number, la1: number, lo2: any, la2: any) {
const oneangle = Math.PI / 180.0
const La1 = la1 * oneangle
const La2 = la2 * oneangle
const La3 = La1 - La2
const Lb3 = lo1 * oneangle - lo2 * oneangle
const s = 2 * Math.asin(
Math.sqrt(
Math.sin(La3 / 2) ** 2
+ Math.cos(La1)
* Math.cos(La2)
* Math.sin(Lb3 / 2) ** 2
)
)
// 地球半径 6378.137 km
return +(s * 6378.137).toFixed(4)
}
下载文件
注意
Safari 手机浏览器自动添加后缀问题
ts
/**
* 下载文件
*/
export function downloadFile(response: any) {
const filename = response.headers['content-disposition'].split(';')[1].split('=')[1]
// TODO Safari 手机浏览器自动添加后缀问题
const blob = new Blob([response.data], { type: 'application/octet-stream;charset=utf-8' })
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.setAttribute('download', decodeURI(filename))
link.click()
URL.revokeObjectURL(link.href)
}
内容复制封装
兼容新API复制方案, 复制思路通过js 创建虚拟inputDOM, 调用全选功能
调用 document.execCommand('copy')
进行复制
ts
/**
* 复制功能
* @param text 复制内容
* @return
*/
export async function copyToClipboard(text: any) {
try {
// 新API 复制接口
return await navigator.clipboard.writeText(text)
}
catch {
const textRef = document.createElement('textarea')
// 获取当前获得焦点的元素
textRef.value = text
// 防止键盘在手机上显示
textRef.setAttribute('readonly', '')
// css3 渲染限制 不在视图内不渲染
textRef.style.contain = 'strict'
textRef.style.position = 'absolute'
textRef.style.left = '-9999px'
textRef.style.fontSize = '12pt' // 防止在iOS上缩放
document.body.appendChild(textRef)
textRef.select()
// iOS的选择解决方案
textRef.selectionStart = 0
textRef.selectionEnd = text.length
document.execCommand('copy')
document.body.removeChild(textRef)
}
}
鼠标滑动复制
鼠标滑动复制通过 document.execCommand('copy')
进行复制
ts
/**
* 鼠标滑动后复制
*/
export function mouseHoverCopy() {
const selection = document.getSelection()
// 鼠标滑动复制
const originalRange = selection
? selection.rangeCount > 0 && selection.getRangeAt(0)
: null
if (originalRange) {
// 清楚鼠标选中内容
selection?.removeAllRanges()
// 添加选中内容
selection?.addRange(originalRange)
document.execCommand('copy')
}
}
/**
* 获取选中内容
*/
export function getSelectText() {
return document.getSelection()?.toString() || ''
}
封装日期函数绑定原型
TypeScript 文件下需要提前声明类型
点击查看
ts
export const n2 = (text: any) => text.toString().padStart(2, '0')
class DateTs extends Date {
constructor(...args: any[]) {
if (!args[0]) {
super()
return
}
if (args.length > 1) {
super(...args as [number])
return
}
if (args.length === 1 && ['string', 'number'].includes(typeof args[0])) {
// TODO 处理传入的只有时间
if (typeof args[0] === 'string' && !args[0].includes('-'))
args[0] = `0000-00-00 ${args}`
super(args[0])
}
}
private o = {
M: this.getMonth() + 1,
d: this.getDate(),
h: this.getHours(),
m: this.getMinutes(),
s: this.getSeconds(),
}
dateToArray(date: string) {
return date.trim().split(/[-, ,:]/).map(Number)
}
/**
* 格式化日期
* @param {string} fmt yyyy-MM-dd hh:mm:ss
*/
format(fmt = 'yyyy-MM-dd') {
const fo = {
'M+': this.getMonth() + 1,
'd+': this.getDate(),
'h+': this.getHours(),
'm+': this.getMinutes(),
's+': this.getSeconds(),
}
const yearRes = fmt.match(/y+/)
if (yearRes)
fmt = fmt.replace(/(y+)/, (`${this.getFullYear()}`).slice(0, yearRes[0].length))
Object.entries(fo).forEach(([re, val]) => {
const oRe = new RegExp(re)
const resVal = String(fmt).match(oRe)
if (resVal)
fmt = fmt.replace(oRe, resVal[0].length === 1 ? val : n2(val))
})
return fmt
}
add(n: number, type: 'M' | 'd' | 'h' | 'm' | 's') {
this.setDate(this.o[type] + n)
return this
}
subtract(n: number, type: 'M' | 'd' | 'h' | 'm' | 's') {
this.setDate(this.o[type] - n)
return this
}
isSame(date: string, _type: string) {
const fmtAbbr = ['y', 'M', 'd', 'h', 'm', 's']
const format = date.replace(/\d+/g, (e) => {
const t = fmtAbbr.shift()
return Array.from({ length: e.length }).map(() => t).join('')
})
return this.format(format) === date
}
lastWeek() {
const nowDay = this.getDate()
const nowDayOfWeek = this.getDay()
this.setDate(nowDay - (nowDayOfWeek || 7) - 6)
return this.format('yyyy-MM-dd')
}
}
export function datejs(date?: string | Date | number) {
return new DateTs(date)
}