utils工具库

该文章提供了一系列JavaScript实用工具函数,包括活动时间验证、长按与滑动事件、动态添加script和link标签、预加载资源、DOM操作、本地存储、JSONP请求、点击和曝光埋点等,适用于前端开发中的多种场景。
摘要由CSDN通过智能技术生成

utils工具

export default {
    isActivityTime, // 判断是否在活动时间内
    longPress,  // 长按触发回调 或 滑动
    appendScript, // 动态添加script标签 到head
    appendLink,   // 动态创建link标签到 head 适用用预加载
    preloadFont,  // 预加载字体
    addStyleToHead, // 项head创建<style>标签 添加全局样式
    isWx,           // 是否是微信环境
    isComWx,        // 是否是企业微信环境
    getUUid,        // 获取uuid值
    objToUrl,       // obj对象转url参数
    jsonp,          // jsonp 请求
    clickLog,       // 点击埋点
    exposureLog,    // 曝光埋点
    sendLog,        // 发送埋点请求
    getUrlParam,    // 获取url参数
    loadRes,        // 加载js || css || style
    _localStorage,          // 本地存储 带时间的
    filterTag,      // 过滤html代码
    random,         // 生成随机数范围
    numberToChinese,// 将阿拉伯数字翻译成中文的大写数字
    DOM,            // 原生dom操作
    parseQueryString,// url参数转对象
    stringifyQueryString, //  对象序列化【对象转url参数】
    _sessionStorage,  //  sessionStore定时失效
    scrollIntoId,     // 定位到页面指定位置
    downloadUrlFile,  // 前端下载文件

}

/**
 * 活动时间效验
 * @param {*} startTime 
 * @param {*} endTime 
 * @param {*} systemTime 
 * @param {*} isReturnCode 
 * @returns 
 */
function isActivityTime(startTime, endTime, systemTime = Date.now(), isReturnCode = false) {
    console.table([
        {
            startTime,
            endTime,
            systemTime,
            isReturnCode,
            startTimeStr: new Date(startTime).toLocaleString(),
            endTimeStr: new Date(endTime).toLocaleString(),
            systemTimeStr: new Date(systemTime).toLocaleString()
        }
    ])
    const isFail = (!startTime || !endTime || startTime == endTime)
    const startResult = (systemTime > startTime)
    const endResult = systemTime <= endTime
    const result = (startResult && endResult)
    if (isReturnCode) {
        if (isFail) {
            // 开始时间 或结束时间不正确
            return 1
        } else if (!startResult) {
            // 活动未开始
            return 2
        } else if (!endResult) {
            // 活动已结束
            return 3
        } else {
            return 4
        }
    } else {
        return (!isFail && result)
    }
}

/**
 * 长按方法 或者 向下滑动
 * @param {*} fn  长按执行回调
 * @param {*} dom  绑定事件的dom节点
 */
function longPress(fn = () => { }, dom) {
    let timeout = 0;
    const $this = dom;
    $this.addEventListener('touchstart', () => {
        timeout = setTimeout(fn, 800); // 长按时间超过800ms,则执行传入的方法 
    }, false);
    $this.addEventListener('touchend', () => {
        clearTimeout(timeout); // 长按时间少于800ms,不会执行传入的方法
    }, false);
}

/**
 * 向下滑动
 * @param {*} fn  长按执行回调
 * @param {*} dom 绑定事件的dom节点
 */
export function touchMove(fn = () => { }, dom, direction) {
    let timeout = 0;
    const $this = dom;
    let startClientX = 0
    let startClientY = 0
    let moveClientX = 0
    let moveClientY = 0
    $this.addEventListener('touchstart', (e) => {
        // console.info("touchstart e", e.touches[0])
        startClientX = e.touches[0].clientX
        startClientY = e.touches[0].clientY
        timeout = setTimeout(() => {
            console.info("startClientY", startClientY)
            console.info("moveClientY", moveClientY)
            if (moveClientY - startClientY < 15) {
                return
            }
            fn()
        }, 200); // 长按时间超过800ms,则执行传入的方法 
    }, false);
    $this.addEventListener('touchmove', (e) => {
        // console.info("touchmove e", e.touches[0])
        moveClientX = e.touches[0].clientX
        moveClientY = e.touches[0].clientY
    }, false);
    //  长按时间少于200ms,不会执行传入的方法
    $this.addEventListener('touchend', () => clearTimeout(timeout), false);
}



/**
 * 动态追加script
 * @param {*} url 
 * @returns 
 */
function appendScript(url) {
    return new Promise((resolve, reject) => {
        const el = document.createElement('script')
        el.src = url
        el.onload = function () {
            resolve()
        }
        el.onerror = function () {
            reject(`append script failed: ${url}`)
            document.head.removeChild(el)
        }
        document.head.appendChild(el)
    })
}


export const AS_CONST = {
    JS: "script",
    FONT: "font",
    STYLE: "style",
    AUDIO: "audio",
    VIDEO: "video",
    DOCUMENT: "document",
    IMAGE: "image",
    FETCH: "fetch",
    WORKER: "worker"
}
/**
 * 动态追加link
 * @param {*} url 
 * @returns 
 */
function appendLink(url, type = AS_CONST.FONT, onload, onerror) {
    return new Promise((resolve) => {
        const link = document.createElement('link')
        link.rel = 'preload'
        link.href = url
        link.as = type
        link.crossOrigin = 'anonymous'
        link.onload = () => {
            onload && onload()
            resolve(true)
            document.head.removeChild(link)
        }
        link.onerror = () => {
            onerror && onerror()
            resolve(false)
            document.head.removeChild(link)
        }
        document.head.appendChild(link)
    })
}


/**
 * 添加样式到<head> style标签中
 * @param {string} styleInnerHTML
 */
function addStyleToHead(styleInnerHTML) {
    const style = document.createElement('style')
    style.id = Math.random()
    style.innerHTML = styleInnerHTML
    document.getElementsByTagName('head')[0].appendChild(style)
}

/**
 * 预加载字体
 * @param {*} url 字体url
 * @param {*} fontName 字体名字
 */
function preloadFont(url, fontName) {
    appendLink(url, "font", addStyleToHead(`
        @font-face {
            font-family: '${fontName}';
            src: url('${url}')
        }
    `))
}


/**
 * 是否是微信环境
 */
function isWx() {
    return /micromessenger/i.test(navigator.userAgent);
}
/**
 * 是否是企业微信
 */
function isComWx() {
    return /wxwork/i.test(navigator.userAgent);
}

/**
 * 获取uuid
 */
function getUUid() {
    crypto.randomUUID()
}

/**
 * jsonp 请求
 * @param {*} url 
 * @param {*} params 
 */
function jsonp(url, params) {
    const src = url + '?' + objToUrl(params);
    const scriptEl = document.createElement('script');
    scriptEl.src = src;
    scriptEl.onload = function () {//body考虑改成head
        document.body.removeChild(scriptEl);
    };
    scriptEl.onerror = function () {
        document.body.removeChild(scriptEl);
    };
    document.body.appendChild(scriptEl);
}

/**
 * 对象参数的处理
 * @param data
 * @returns {string}
 */
function objToUrl(data) {
    data = data ?? false
    if (!data) return "";//没有就返回空字符
    const arr = [];
    for (const param in data) {
        arr.push(encodeURIComponent(param) + '=' + encodeURIComponent(data[param]));
    }
    //不缓存
    arr.push('_=' + Date.now());
    return arr.join('&');
}

/**
 * 发送埋点
 * @param {*} type 埋点类型
 * @param {*} id 埋点id
 * @param {*} params  埋点参数
 */
function sendLog(type, id, params = {}) {
    const projectID = CFG.projectId;
    const appID = CFG.appID
    const domain = '//embedlog.duiba.com.cn';
    const dpm = `${appID || 'appID'}.110.${id}.1`;// TODO appID注意默认写死一个,已防链接没有
    const dcm = `202.${projectID || 'projectID'}.0.0`;
    const params = {
        appId: appID,
        dpm,
        dcm,
        domain
    };
    // 进行参数重置
    Object.assign(params, params)
    const isExposure = (type == "exposure");
    if (isExposure) {
        // 曝光
        // eslint-disable-next-line @spark/best-practices/no-url-in-js
        jsonp('//embedlog.duiba.com.cn/exposure/standard', params);
    } else {
        // 点击操作
        jsonp('/log/click', params);
    }
}

/**
 * 点击埋点
 * @param {*} id 点击埋点id
 * @param {*} params 合并埋点的参数
 */
function clickLog(id, params) {
    sendLog("click", id, params)
}


/**
 * 曝光埋点
 * @param {*} id  埋点ID
 * @param {*} params  埋点合并参数
 */
function exposureLog(id, params) {
    sendLog("exposure", id, params)
}


/**
 * 获取url参数
 * @param {*} name 
 * @returns 
 */
export function getUrlParam(name) { // 获取url参数
    let reg = new RegExp('(^|&?)' + name + '=([^&]*)(&|$)', 'i')
    let r = window.location.href.substr(1).match(reg)
    if (r != null) {
        return decodeURI(r[2])
    }
    return undefined
}

/**
 * 加载js || css || style
 * @param {*} name 
 * @param {*} type 
 * @param {*} fn 
 */
export const loadRes = function (name, type, fn) { // 加载js || css || style
    let ref
    if (type === 'js') { // 外部js
        ref = document.createElement('script')
        ref.setAttribute('type', 'text/JavaScript')
        ref.setAttribute('src', name)
    } else if (type === 'css') { // 外部css
        ref = document.createElement('link')
        ref.setAttribute('rel', 'stylesheet')
        ref.setAttribute('type', 'text/css')
        ref.setAttribute('href', name)
    } else if (type === 'style') { // style
        ref = document.createElement('style')
        ref.innerhtml = name
    }
    if (typeof ref !== 'undefined') {
        document.getElementsByTagName('head')[0].appendChild(ref)
        ref.onload = function () { // 加载完成执行
            typeof fn === 'function' && fn()
        }
    }
}

/**
 * 本地存储
 */
export const _localStorage = { // 本地存储
    set: function (name, value, day) { // 设置
        let d = new Date()
        let time = 0
        day = (typeof (day) === 'undefined' || !day) ? 1 : day // 时间,默认存储1天
        time = d.setHours(d.getHours() + (24 * day)) // 毫秒
        localStorage.setItem(name, JSON.stringify({
            data: value,
            time: time
        }))
    },
    get: function (name) { // 获取
        let data = localStorage.getItem(name)
        if (!data) {
            return null
        }
        let obj = JSON.parse(data)
        if (new Date().getTime() > obj.time) { // 过期
            localStorage.removeItem(name)
            return null
        } else {
            return obj.data
        }
    },
    clear: function (name) { // 清空
        if (name) { // 删除键为name的缓存
            localStorage.removeItem(name)
        } else { // 清空全部
            localStorage.clear()
        }
    }
}
/**
 * 过滤html代码
 * @param {*} str 
 * @returns 
 */
export const filterTag = function (str) { // 过滤html代码(把<>转换)
    str = str.replace(/&/ig, '&')
    str = str.replace(/</ig, '<')
    str = str.replace(/>/ig, '>')
    str = str.replace(' ', ' ')
    return str
}

/**
 * 生成随机数范围
 * @param {*} min 
 * @param {*} max 
 * @returns 
 */
export const random = function (min, max) { // 生成随机数范围
    if (arguments.length === 2) {
        return Math.floor(min + Math.random() * ((max + 1) - min))
    } else {
        return null
    }
}

/**
 * 阿拉伯数字转中文大写数字
 * @param {*} num 
 * @returns 
 */
export const numberToChinese = function (num) { // 将阿拉伯数字翻译成中文的大写数字
    let AA = new Array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十')
    let BB = new Array('', '十', '百', '仟', '萬', '億', '点', '')
    let a = ('' + num).replace(/(^0*)/g, '').split('.')
    let k = 0
    let re = ''
    for (let i = a[0].length - 1; i >= 0; i--) {
        switch (k) {
            case 0:
                re = BB[7] + re
                break
            case 4:
                if (!new RegExp('0{4}//d{' + (a[0].length - i - 1) + '}$').test(a[0])) {
                    re = BB[4] + re
                }
                break
            case 8:
                re = BB[5] + re
                BB[7] = BB[5]
                k = 0
                break
        }
        if (k % 4 === 2 && a[0].charAt(i + 2) !== 0 && a[0].charAt(i + 1) === 0) {
            re = AA[0] + re
        }
        if (a[0].charAt(i) !== 0) {
            re = AA[a[0].charAt(i)] + BB[k % 4] + re
        }
        k++
    }
    if (a.length > 1) { // 加上小数部分(如果有小数部分)
        re += BB[6]
        for (let i = 0; i < a[1].length; i++) {
            re += AA[a[1].charAt(i)]
        }
    }
    if (re === '一十') {
        re = '十'
    }
    if (re.match(/^一/) && re.length === 3) {
        re = re.replace('一', '')
    }
    return re
}

/**
 * 原生dom操作
 */
export const DOM = {
    $: function (selector) {
        let type = selector.substring(0, 1)
        if (type === '#') {
            if (document.querySelecotor) return document.querySelector(selector)
            return document.getElementById(selector.substring(1))
        } else if (type === '.') {
            if (document.querySelecotorAll) return document.querySelectorAll(selector)
            return document.getElementsByClassName(selector.substring(1))
        } else {
            return document['querySelectorAll' ? 'querySelectorAll' : 'getElementsByTagName'](selector)
        }
    },
    hasClass: function (ele, name) { /* 检测类名 */
        return ele.className.match(new RegExp('(\\s|^)' + name + '(\\s|$)'))
    },
    addClass: function (ele, name) { /* 添加类名 */
        if (!this.hasClass(ele, name)) ele.className += ' ' + name
    },
    removeClass: function (ele, name) { /* 删除类名 */
        if (this.hasClass(ele, name)) {
            let reg = new RegExp('(\\s|^)' + name + '(\\s|$)')
            ele.className = ele.className.replace(reg, '')
        }
    },
    replaceClass: function (ele, newName, oldName) { /* 替换类名 */
        this.removeClass(ele, oldName)
        this.addClass(ele, newName)
    },
    siblings: function (ele) { /* 获取兄弟节点 */
        console.log(ele.parentNode)
        let chid = ele.parentNode.children,
            eleMatch = []
        for (let i = 0, len = chid.length; i < len; i++) {
            if (chid[i] !== ele) {
                eleMatch.push(chid[i])
            }
        }
        return eleMatch
    },
    getByStyle: function (obj, name) { /* 获取行间样式属性 */
        if (obj.currentStyle) {
            return obj.currentStyle[name]
        } else {
            return getComputedStyle(obj, false)[name]
        }
    },
    domToString: function (htmlDOM) { /* DOM转字符串 */
        var div = document.createElement('div')
        div.appendChild(htmlDOM)
        return div.innerHTML
    },
    stringToDom: function (htmlString) { /* 字符串转DOM */
        var div = document.createElement('div')
        div.innerHTML = htmlString
        return div.children[0]
    }
}

/**
 * url参数转对象
 * @param {*} url 
 * @returns 
 */
export const parseQueryString = function (url) { //url参数转对象
    url = !url ? window.location.href : url;
    if (url.indexOf('?') === -1) {
        return {};
    }
    let search = url[0] === '?' ? url.substr(1) : url.substring(url.lastIndexOf('?') + 1);
    if (search === '') {
        return {};
    }
    search = search.split('&');
    let query = {};
    for (let i = 0; i < search.length; i++) {
        let pair = search[i].split('=');
        query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
    }
    return query;
}

/**
 * 对象序列化【对象转url参数】
 * @param {*} obj 
 * @returns 
 */
export const stringifyQueryString = function (obj) { //对象序列化【对象转url参数】
    if (!obj) return '';
    let pairs = [];
    for (let key in obj) {
        let value = obj[key];
        if (value instanceof Array) {
            for (let i = 0; i < value.length; ++i) {
                pairs.push(encodeURIComponent(key + '[' + i + ']') + '=' + encodeURIComponent(value[i]));
            }
            continue;
        }
        pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
    }
    return pairs.join('&');
}


/**
 * 定位到页面指定位置
 * @param {*} id 
 */
export function scrollIntoId(id) { // 需要在跳转到的目标做id绑定操作
    document.getElementById(id).scrollIntoView();
}

/**
 * sessionStore定时失效
 */
export const _sessionStorage = {
    getItem(key) {
        let info = sessionStorage.getItem(key)
        if (info) {
            const { time, inTime, key, value } = info = JSON.parse(info)
            const nowTime = new Date().getTime()
            console.log('时间对比 nowTime,inTime,time', nowTime, inTime, time)
            if (!time || (nowTime - inTime <= time)) { //说明有效
                return value
            } else {
                console.log('说明已经过期')
                sessionStorage.removeItem(key)
            }
        }
    },
    setItem(key, value, time) {
        sessionStorage.setItem(key, JSON.stringify({
            time,
            inTime: new Date().getTime(),
            key,
            value
        }))
    },
    removeItem(key) {
        console.log('手动清除session')
        sessionStorage.removeItem(key)
    },
}

/**
 * 前端下载文件
 * @param {*} url 
 * @param {*} name 
 */
export function downloadUrlFile(url, name) {
    console.log('下載的數據 saveAs ==》data', data)
    var urlObject = window.URL || window.webkitURL || window;
    var export_blob = new Blob([data]);
    console.log('document.createElementNS', document.createElementNS)
    if (window.navigator.msSaveBlob) {
        try {
            window.navigator.msSaveBlob(export_blob, `${name}.mp3`)
        } catch (e) {
            console.log(e);
        }
    } else {
        var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a')
        save_link.href = urlObject.createObjectURL(export_blob);
        save_link.download = name;
        save_link.click();
    }
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥肥呀呀呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值