JavaScript 工具函数汇总

JavaScript 工具函数汇总

小小孩
2021-08-05 / 1 评论 / 455 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年02月23日,已超过1002天没有更新,若内容或图片失效,请留言反馈。
精简的代码来实现相对复杂的功能
根据对象路径 path 获取值
const getValueByPath = function(object, prop) {
  prop = prop || '';
  const paths = prop.split('.');
  let current = object;
  let result = null;
  for (let i = 0, j = paths.length; i < j; i++) {
    const path = paths[i];
    if (!current) break;

    if (i === j - 1) {
      result = current[path];
      break;
    }
    current = current[path];
  }
  return result;
};
getValueByPath({a:{b:{c:{d:1}}}},'a.b.c.d') // 1
全局通用的数据类型判断方法
function getType(obj){
  let type  = typeof obj;
  if (type !== "object") {    // 先进行typeof判断,如果是基础数据类型,直接返回
    return type;
  }
  // 对于typeof返回结果是object的,再进行如下的判断,正则返回结果
  return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1'); 
}
对象转化为FormData对象
function getFormData(object) {
    const formData = new FormData()
    Object.keys(object).forEach(key => {
        const value = object[key]
        if (Array.isArray(value)) {
            value.forEach((subValue, i) =>
                formData.append(key + `[${i}]`, subValue)
            )
        } else {
            formData.append(key, object[key])
        }
    })
    return formData
}
生成随机字符串
function ruid(length, chars) {
    chars =
        chars ||
        '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    length = length || 8
    var result = ''
    for (var i = length; i > 0; --i)
        result += chars[Math.floor(Math.random() * chars.length)]
    return result
}
休眠多少毫秒
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))
}
复制内容到剪贴板
function copyToBoard(value) {
    const element = document.createElement('textarea')
    document.body.appendChild(element)
    element.value = value
    element.select()
    if (document.execCommand('copy')) {
        document.execCommand('copy')
        document.body.removeChild(element)
        return true
    }
    document.body.removeChild(element)
    return false
}
获取文件后缀名
function getExt(filename) {
    if (typeof filename == 'string') {
        return filename
            .split('.')
            .pop()
            .toLowerCase()
    } else {
        throw new Error('filename must be a string type')
    }
}
随机获取颜色
function getRandomColor () {
  let rgb = []
  for (let i = 0; i < 3; ++i) {
    let color = Math.floor(Math.random() * 256).toString(16)
    color = color.length == 1 ? '0' + color : color
    rgb.push(color)
  }
  return '#' + rgb.join('')
}
获取过去时间提示
function getOldTimeStr(time) {
  if (!time) {
    return "";
  }
  let oldTimestamp = time;

  if ("string" === typeof time) {
    oldTimestamp =
      new Date(time).getTime() || new Date(time.replace(/-/g, "/")).getTime();
  }

  var todayStartTimestamp = new Date(new Date().toLocaleDateString()).getTime();
  const differTimestamp = Date.now() - oldTimestamp;
  console.log("🚀 ~ olde ~ differTimestamp", differTimestamp);
  if (differTimestamp < 6e4) {
    return "刚刚";
  }
  if (differTimestamp < 36e5) {
    return Math.floor(differTimestamp / 6e4) + "分钟前";
  }

  if (differTimestamp < 864e5) {
    return oldTimestamp >= todayStartTimestamp
      ? Math.floor(differTimestamp / 36e5) + "小时前"
      : "昨天";
  }

  if (differTimestamp < 1728e5) {
    return oldTimestamp >= todayStartTimestamp - 864e5 ? "昨天" : "前天";
  }

  if (
    differTimestamp < 2592e5 &&
    oldTimestamp >= todayStartTimestamp - 1728e5
  ) {
    return "前天";
  }

  const oldTime = new Date(oldTimestamp);
  const oldYear = oldTime.getFullYear();
  let oldTimeStr = `${oldTime.getMonth() + 1}.${oldTime.getDate()}`;

  if (new Date().getFullYear() !== oldYear) {
    oldTimeStr = `${oldYear}.${oldTimeStr}`;
  }
  return oldTimeStr;
}

//例子

getOldTimeStr('2021/8/4')
基于atob和btoa的base64编码和解码
function utf8_to_b64( str ) {
  return window.btoa(unescape(encodeURIComponent( str )));
}

function b64_to_utf8( str ) {
  return decodeURIComponent(escape(window.atob( str )));
}
基于URL或者Crypto.getRandomValues生成UUID
function genUUID() {
    const url = URL.createObjectURL(new Blob([]));
    // const uuid = url.split("/").pop();
    const uuid = url.substring(url.lastIndexOf('/')+ 1);
    URL.revokeObjectURL(url);
    return uuid;
}
genUUID();

function uuidv4() {
  return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
    (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
}
uuidv4() 
基于 toLocaleString 金额千分位
function formatMoney(num){
    return (+num).toLocaleString("en-US");
}
滑滚动页面到顶部
// smooth 选项在Safari上支持不好
function scrollToTop(){
    window.scrollTo({
        left: 0,
        top: 0,
        behavior: 'smooth
    })
}

function scrollToTop() {
    let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    if (scrollTop > 0) {
        window.requestAnimationFrame(scrollToTop);
        window.scrollTo(0, scrollTop - scrollTop / 8);
    }
};
相对地址转换为绝对地址
function realativeToAbs(href) {
    let aEl = document.createElement("a");
    aEl.href = href;    

    const result = aEl.href;
    aEl = null;
    return result;
}
Promise顺序执行

让Promise顺序的执行,并支持初始化参数和结果作为参数传递。

function runPromises(promiseCreators, initData) {
    return promiseCreators
        .reduce((promise, next) => promise
                .then((data) => next(data))
            , Promise.resolve(initData));
}

// 示例
var promise1 = function (data = 0) {
    return new Promise(resolve => {
        resolve(data + 200);
    });
}
var promise2 = function (data) {
    return new Promise(resolve => {
        resolve(data - 100);
    });
}

runPromises([promise1, promise2], 100).then(res=>console.log(res));
延时执行delay

延时执行某函数,且只会执行一次。

function delay(fn = () => , delay = 5000, context = null) {
    let ticket = null;
    let runned = false;
    return {
        run(...args) {
            return new Promise((resolve, reject) => {
                if (runned === true) {
                    return;
                }
                runned = true;
                ticket = setTimeout(async () => {
                    try {
                        const res = await fn.apply(context, args);
                        resolve(res);
                    } catch (err) {
                        reject(err)
                    }
                }, delay)
            })
        },
        cancel: () => {
            clearTimeout(ticket);
        }
    }
}

//示例
delay(function () {
    console.log("你们好");
}).run();

const { run, cancel } = delay(function (name) {
    console.log("你好:", name);
});

run("吉他");
run("吉他");
禁止选择和复制
['contextmenu', 'selectstart', 'copy'].forEach(function(ev){
    document.addEventListener(ev, function(ev){
        ev.preventDefault();
        ev.returnValue = false;
    })
});

当然也有CSS方案

body {
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    -khtml-user-select: none;
    user-select: none;
}
相对地址转换为绝对地址

基于当前页面的相对地址转换为绝对地址。

function realativeToAbs(href) {
    let aEl = document.createElement("a");
    aEl.href = href;    

    const result = aEl.href;
    aEl = null;
    return result;
}
带图带事件的桌面通知
function doNotify(title, options = {}, events = {}) {
    const notification = new Notification(title, options);
    for (let event in events) {
        notification[event] = events[event];
    }
}

function notify(title, options = {}, events = {}) {
    if (!("Notification" in window)) {
        return console.error("This browser does not support desktop notification");
    }
    else if (Notification.permission === "granted") {
        doNotify(title, options, events);
    } else if (Notification.permission !== "denied") {
        Notification.requestPermission().then(function (permission) {           
            if (permission === "granted") {
                doNotify(title, options, events);
            }
        });
    }
}

//示例
     notify("中奖提示", {
            icon: "https://yuye.fun/logo.png",
            body: "恭喜你,抽中一等奖",
            tag: "羽叶风雨"
        }, {
            onclick(ev) {
                console.log(ev);
                ev.target.close();
                window.focus();
            }
        })

bytesToSize

const bytesToSize = (bytes, decimal = 2) => {
  if (0 == bytes) return "0 Bytes";
  const Binary = 1024;
  const UNITS = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
  const unitIndex = Math.floor(Math.log(bytes) / Math.log(Binary));
  return `${parseFloat((bytes / Math.pow(Binary, unitIndex)).toFixed(decimal))} ${UNITS[unitIndex]}`;
};
0

评论 (1)

取消
  1. 头像
    马内
    Windows 7 · Google Chrome

    JavaScript 做出来的工具,真是丰富

    回复