前端日常方法总结

💡 在前端的方法使用中,一些未被封装,但是常用的方法的总结
工具类方法

保留小数精度问题

/**

  • @param {number | string} num 数值
  • @param {number | string} percision 精度,保留几位小数
  • @return 保留小数后的字符串
    */
    function numberWithPercision(num, percision = 0) {
    if (isNaN(num) || isNaN(percision) || percision < 0 || percision > 100) {
    return ‘’;
    }
    percision = Number(percision);
    if (percision === 0) {
    return Math.round(num).toString();
    }
    const sign = num >= 0 ? ‘’ : ‘-’;
    let tNum = Math.abs(num).toString();
    const [integer, decimals = ‘’] = tNum.split(‘.’);
    const decimalsLen = decimals.length;
    if (percision >= decimalsLen) {
    return sign + integer + ‘.’ + decimals + ‘0’.repeat(percision - decimalsLen);
    }
    tNum = Math.round(integer + decimals.substr(0, percision) + ‘.’ +
    decimals.substr(percision - decimalsLen)).toString();
    tNum = tNum.padStart(integer.length + percision, ‘0’);
    const len = tNum.length - percision;
    return sign + tNum.substr(0, len) + ‘.’ + tNum.substr(len);
    }

日期format

/**

  • @param {string | Date} date 日期

  • @param {string | Array} format 分隔符 或 年月日

  • @return {string} 格式化日期 或 完整年月日日期
    */
    function formatDate(date, format = ‘-’) {
    if (!date) {
    return ‘’;
    }

    let year = ‘’;
    let month = ‘’;
    let day = ‘’;
    if (date instanceof Date) {
    year = date.getFullYear();

     month = date.getMonth() + 1;
     if (month < 10) {
         month = '0' + month;
     }
     
     day = date.getDate();
     if (day < 10) {
         day = '0' + day;
     }
    

    } else {
    const dateStr = date.replace(/[^0-9]/g, ‘’);

     year = dateStr.slice(0, 4);
     month = dateStr.slice(4, 6);
     day = dateStr.slice(6);
    

    }

    if (!Array.isArray(format)) {
    return year + format + month + (day ? format + day : ‘’);
    }

    const [yearStr, monthStr, dayStr] = format;
    return (yearStr ? year + yearStr : ‘’) +
    (monthStr ? month + monthStr : ‘’) +
    (dayStr ? day + dayStr : ‘’);
    }

// e.g.
formatDate(new Date(), ‘’); // 20231001
formatDate(new Date(), ‘-’); // 2023-10-01
formatDate(‘20231001’, ‘/’); // 2023/10/01

formatDate(new Date(), [‘年’, ‘月’, ‘日’]); // 2023年10月01日
formatDate(‘20231001’, [‘年’, ‘月’]); // 2023年10月
formatDate(‘20231001’, [‘’, ‘月’, ‘日’]); // 10月01日

时间format

/**

  • @param {Date} date 日期
  • @param {string} format 分隔符
  • @return {string} 格式化时间
    */
    function getHMS = (date: Date, format = ‘:’) {
    return [
    date.getHours().toString().padStart(2, ‘0’),
    date.getMinutes().toString().padStart(2, ‘0’),
    date.getSeconds().toString().padStart(2, ‘0’),
    ].join(format);
    }

填充内容保留两位小数format

/**

  • @param {string} value 需要保留两位小数的输入内容
  • @return 保留两位小数的字符串
    /
    function formatValueReg(value) {
    return value
    .replace(/[^\d.]/g, ‘’)
    .replace(‘.’, ‘KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲’)
    .replace(/./g, ‘’)
    .replace(‘KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲’, ‘.’)
    .replace(/.{2,}/g, ‘.’)
    .replace(/^(-)
    (\d+).(\d\d).*$/, ‘$1$2.$3’);
    }

倒计时

/**

  • @param {number} time 倒计时时长,单位s
  • @return
    */
    function countDown(time) {
    let t = time;
    let timer;
    return {
    minus: (callback) => {
    timer = setInterval(() => {
    t --;
    callback(t);
    if (t <= 0) {
    clearInterval(timer);
    timer = undefined;
    }
    }, 1000);
    },
    clear: () => {
    if (timer) {
    clearInterval(timer);
    timer = undefined;
    }
    }
    }
    }

// 使用示例
isSendingSms = true;
const cd = countDown(60);
cd.minus((t) => {
// 保证再次调用时,清除上一次的倒计时
if (!isSendingSms) {
cd.clear();
return;
}
smsCountDown = t;
if (t <= 0) {
reset(‘重新发送’);
}
});

获取相对某个日期的方法

/**

  • @param {Date} date 日期值
  • @param {number} year 增减年份,增为正,减为负
  • @param {number} month 增减月份,增为正,减为负
  • @param {number} day 增减日期,增为正,减为负
  • @return {Date} 日期
    */
    function getDate(date, year = 0, month = 0, day = 0) {
    // date格式不要携带 “-” 使用 “/” ,否则ios会报错。 例如 new Date(‘2023/07/28’)
    if (year) {
    date.setFullYear(date.getFullYear() + year);
    }
    if (month) {
    date.setMonth(date.getMonth() + month);
    }
    if (day) {
    date.setDate(date.getDate() + day);
    }
    return date;
    }

// e.g.
// i.e., today is Tue Aug 01 2023 10:26:25 GMT+0800 (中国标准时间)
getDate(new Date(), 1, 0, 0); // Tue Oct 01 2024 00:00:01 GMT+0800 (中国标准时间)
getDate(new Date(), 1, 1, 0); // Tue Nov 01 2023 00:00:01 GMT+0800 (中国标准时间)
getDate(new Date(), 1, 1, 1); // Tue Nov 02 2023 00:00:01 GMT+0800 (中国标准时间)
getDate(new Date(), -1, -1, -1); // Tue Aug 31 2022 00:00:01 GMT+0800 (中国标准时间)

复制

/**

  • @param {string} value 需要复制的值

  • @param {function} callback 回调方法,返回成功失败结果

  • @return
    */
    function copyValue(value, callback) {
    if (navigator.userAgent.match(/(iPhone|iPod|iPad);?/i)) {
    try {
    const copyInput = document.createElement(‘input’);
    copyInput.value = value;
    copyInput.style.opactiy = ‘0’;
    document.body.appendChild(copyInput);
    const editable = copyInput.contentEditable;
    const readonly = copyInput.readOnly;
    copyInput.contentEditable = true;
    copyInput.readOnly = false;
    const range = document.createRange();
    range.selectNodeContents(copyInput);
    const sel = window.getSelection();
    sel.removeAllRange();
    sel.addRange(range);
    copyInput.setSelectionRange(0, 9999);
    copyInput.contentEditable = editable;
    copyInput.readOnly = readonly;
    const successful = document.execCommand(‘copy’);
    copyInput.blur();
    if (successful) {
    callback(‘复制成功’);
    } else {
    callback(‘复制失败’);
    }
    document.body.removeChild(copyInput);
    } catch (error) {
    }
    return;
    }

    try {
    const copyInput = document.createElement(‘input’);
    copyInput.value = value;
    document.body.appendChild(copyInput);
    copyInput.select();
    const successful = document.execCommand(‘copy’);
    if (successful) {
    callback(‘复制成功’);
    } else {
    callback(‘复制失败’);
    }
    document.body.removeChild(copyInput);
    } catch (error) {
    }
    }

金额转换

/**

  • @param {number | string} amount 金额
  • @param {number} percision 精度
  • @return {string} 千分隔字符串
    */
    function convertToWriting(amount, percision = 2) {
    if (!amount) {
    return ‘’;
    }
    // numberWithPercision 是上面的保留小数精度方法
    const temp = numberWithPercision(amount, percision).split(‘.’);
    return temp[0].replace(/(\d)(?=(\d{3})+$)/g, ‘$1,’) + ‘.’ + (temp[1] || ‘00’);
    }

// 示例
// convertToWriting(4561235.157, 2) => 4,561,235.16

乘法运算

/**

  • @param {number | string} val 被乘数
  • @param {number | string} rate 乘数
  • @return {number} 积,返回值有精度问题,若要处理精度,需配合numberWithPercision使用
    */
    function floatMul(val, rate) {
    val = val.toString();
    rate = rate.toString();
    let baseNum = 0;
    try {
    baseNum += val.split(‘.’)[1].length;
    } catch (e) {
    }
    try {
    baseNum += rate.split(‘.’)[1].length;
    } catch (e) {
    }
    return Number(val.replace(‘.’, ‘’)) * Number(rate.replace(‘.’, ‘’)) / Math.pow(10, baseNum);
    }

除法运算

/**

  • @param {number | string} val 被除数
  • @param {number | string} rate 除数
  • @return {number} 商,返回值有精度问题,若要处理精度,需配合numberWithPercision使用
    */
    function floatMul(val, rate) {
    val = val.toString();
    rate = rate.toString();
    let baseNum1 = 0;
    let baseNum2 = 0;
    let baseNum3 = 0;
    let baseNum4 = 0;
    try {
    baseNum1 = val.split(‘.’)[1].length;
    } catch (e) {
    baseNum1 = 0;
    }
    try {
    baseNum2 = rate.split(‘.’)[1].length;
    } catch (e) {
    baseNum2 = 0;
    }
    baseNum3 = Number(val.replace(‘.’, ‘’));
    baseNum4 = Number(rate.replace(‘.’, ‘’));
    return (baseNum3 / baseNum4) * Math.pow(10, baseNum2 - baseNum1);
    }

加减法

/**

  • @param {number} num1 加数,可为负值
  • @param {number} num2 加数,可为负值
  • @return {number} 和,返回值有精度问题,若要处理精度,需配合numberWithPercision使用
    */
    function addNum(num1, num2) {
    let sq1 = 0;
    let sq2 = 0;
    let m = 0;
    try {
    sq1 = num1.toString().split(‘.’)[1].length;
    } catch (e) {
    }
    try {
    sq2 = num2.toString().split(‘.’)[1].length;
    } catch (e) {
    sq2 = 0;
    }
    m = Math.pow(10, Math.max(sq1, sq2));
    return (num1 * m + num2 * m) / m;
    }

生成某个范围内规律的数字数组

/**

  • @param {number} start 数值,可为负值
  • @param {number} end 数值,可为负值
  • @param {number} range 数值,可为负值
  • @return {Array} 从start到end之间间隔range的数值数组
    */
    function rangeArray(start, end, range = 1) {
    if (range === 0 || range < 0 && start < end || range > 0 && start > end) {
    return [start];
    }
    return Array(Math.floor((end - start) / range) + 1).fill(0).map((v, i) => {
    return range * i + start;
    });
    }

// 示例
rangeArray(1, 7); // [1, 2, 3, 4, 5, 6, 7];
rangeArray(7, 1); // [7]
rangeArray(7, 1, -1); // [7, 6, 5, 4, 3, 2, 1];
rangeArray(1, 7, 2) // [1, 3, 5, 7];
rangeArray(1, 7, -1); // [1]
向下取整
// 向下取整千
Math.floor(a / 1000) * 1000
// 示例
// 1234 => 1000
// 1000 => 1000

// 向下取整千,不能和当前值一致
Math.floor((a - 1) / 1000) * 1000
// 示例
// 1234 => 1000
// 2000 => 1000
业务类解决方案
自定义键盘问题——粘贴(仅适用于非密码相关,密码需考虑安全性不可粘贴)

<input :readonly=“isIos” v-model=“inputVal” ref=“input” @paste=“onPaste” />
// 以下是vue + ts里的写法,其他语法可相应转换
export default class Test extends Vue {
private inputValue: string = ‘’;
get inputEl() {
return this.$refs.input as HTMLElement;
}

get isIos() {
    return !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
}

private mounted() {
    this.inputEl.onfocus = () => {
        this.inputFocus();
    };
    // 由于微信浏览器限制,在focus后二次点击input,不会再次触发click事件,需要用原生的方式绑定
    this.inputEl.onclick = () => {
        if (this.isIos) {
            return;
        }
        this.inputFocus();
    };
}

protected inputFocus() {
    if (this.isIos) {
        navigator.clipboard.readText().then((res: any) => {
            console.log(res); // 此为粘贴后的数据
        });
        if (document.activeElement instanceof HTMLElement) {
            document.activeElement.blur();
        }
        return;
    }
    this.inputEl.setAttribute('readonly', 'readonly');
    setTimeout(() => {
        this.inputEl.removeAttribute('readonly');
    });
}

protected onPaste() {
    if (this.isIos) {
        return;
    }
    setTimeout(() => {
        console.log(this.inputVal); // 此为粘贴后的数据
        this.inputVal = ''; // 拿到数据后使用并清空,否则第二次focus会触发自定义键盘的出现
    });
}

}

解决input框输入时键盘遮挡页面元素问题

// vue项目index.html中直接引入或添加此段代码 html页面直接script标签引入
document.body.addEventListener(“focusout”, () => {
// 软键盘收起的事件处理
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;window.scrollTo(0, Math.max(scrollHeight - 1, 0));
}, 100);
});
// 页面关闭可以removeListener
切换页面默认滚动温柔地到顶部
html {
scroll-behavior: smooth;
}
滚动到顶部
const scrollToTop = (element) =>
element.scrollIntoView({ behavior: “smooth”, block: “start” })
滚动到底部
const scrollToBottom = (element) =>
element.scrollIntoView({ behavior: “smooth”, block: “end” })
弹窗后禁止背景滚动
vue环境
// 可封装至全局
const preventDefaultAction = () => {
const defaultAction = (e) => {
e.preventDefault();
};

return {
    // 禁止滚动
    stop: () => {
        document.body.style.overflow='hidden';
        document.addEventListener('touchmove', defaultAction);
    },
    // 取消滚动限制
    move: () => {
        document.body.style.overflow='';
        document.removeEventListener('touchmove', defaultAction);
    }
}

}

小程序环境

// 外层结构加上catch:touchmove事件,当传入值非空时,则阻止默认行为

hello world ~~

开启弹窗 关闭弹窗 Page({ data: { preventDefaultAction: null },
// 弹窗开启,阻止默认事件
openDialog() {
    this.setData({
        preventDefaultAction: true
    })
},

// 弹窗关闭,允许默认行为,外层可滚动
closeDialog() {
    this.setData({
        preventDefaultAction: null
    })  
}

})

  • 24
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值