生成随机颜色

const generateRandomHexColor = () => `#${Math.floor(Math.random() * 0xffffff).toString(16)}`
console.log(generateRandomHexColor())

数组重新随机排序

const shuffle = (arr) => arr.sort(() => Math.random() - 0.5)
const arr = [1, 2, 3, 4, 5]
console.log(shuffle(arr))

防抖

// 初次触发可立即执行
function debounce(fn, wait) {
    let flag = true
    let timer = null
    return function() {
        let context = this;
        let args = arguments;
        clearTimeout(timer)
        if (flag) {
            flag = false
            fn.apply(context, args);
        }
        timer = setTimeout(() => {
            flag = true
        }, wait)
    }
}

节流

// 初次触发可立即执行
function throttle(fn, wait) {
    let flag = true;
    return function() {
        let context = this;
        let args = arguments;
        if (flag) {
            flag = false
            fn.apply(context, args);
            setTimeout(() => {
                flag = true
            }, wait);
        }
    }
}

数组去重

利用 es6 中的 Map,类似于对象,也是键值对,但键可以是各种类型,键不可以有相同的特性

/** 
 * @function 数组去重 
 * @param arr {Array} 要去重的数组
 * @param key {String} 按某个字段去重 'key'
 * @return {Array} 返回一个新的数组
 */
function removeArrRepeat (arr, key) {
    let map = new Map();
    if (key) {
        return arr.filter(item => !map.has(item[key]) && map.set(item[key], 1));
    }
    else {
        return arr.filter(item => !map.has(item) && map.set(item, 1));
    }
}

两数组交集

/** 
 * @function 求两数组交集
 * @param arr1 {Array} 数组1
 * @param arr2 {Array} 数组2
 * @param key {String} 按某个字段求交集 'key'
 * @return {Array} 返回一个新的数组
 */
function intersection (arr1, arr2, key) {
    if (key) {
        let arr2Ids = arr2.map(item => item[key]);
        return arr1.filter(item => arr2Ids.includes(item[key]))
    }
    else {
        let arr2Ids = arr2.map(item => item);
        return arr1.filter(item => arr2Ids.includes(item))
    }
}

两数组并集

/** 
 * @function 求两数组并集
 * @param arr1 {Array} 数组1
 * @param arr2 {Array} 数组2
 * @param key {String} 合并数组之后去重的字段 'key'
 * @return {Array} 返回一个新的数组
 */
function union (arr1, arr2, key) {
    let mergeArr = [...arr1, ...arr2];
    let map = new Map();
    if (key) {
        return mergeArr.filter(item => !map.has(item[key]) && map.set(item[key], 1))
    }
    else {
        return mergeArr.filter(item => !map.has(item) && map.set(item, 1))
    }
}

两数组差集

/** 
 * @function 求两数组差集
 * @param arr1 {Array} 数组1
 * @param arr2 {Array} 数组1
 * @param key {String} 根据key求差集 'key'
 * @return {Array} 返回 arr2相对arr1的差集
 * */
function differenceSet (arr1, arr2, key) {
    if (key) {
        let arr2Ids = arr2.map(item => item[key]);
        return arr1.filter(item => !arr2Ids.includes(item[key]))
    }
    else {
        let arr2Ids = arr2.map(item => item);
        return arr1.filter(item => !arr2Ids.includes(item))
    }
}

数组排序

let arr = [{name: '张三', age: 10}, {name: '李四', age: 18}, {name: '王五', age: 12}]
arr.sort((a, b) => a.age - b.age);
let arr1 = [2, 1, 5, 10, 22, 3, 5]
arr1.sort((a, b) => b - a);

复制到剪切板

// navigator.clipboard 来访问系统剪切板,以读取系统剪切板的内容
const copyToClipboard = (text) => navigator.clipboard && navigator.clipboard.writeText && navigator.clipboard.writeText(text)
copyToClipboard("Hello World!")

检测暗色主题

// matchMedia() 返回一个新的 MediaQueryList 对象,表示指定的媒体查询字符串解析后的结果。
const isDarkMode = () => window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
console.log(isDarkMode())

滚动到顶部

将元素滚动到顶部最简单的方法是使用 scrollIntoView。设置 block 为 start 可以滚动到顶部;设置 behavior 为 smooth 可以开启平滑滚动。

const scrollToTop = (element) => 
element.scrollIntoView({ behavior: "smooth", block: "start" });

滚动到底部

与滚动到顶部一样,滚动到底部只需要设置 block 为 end 即可。

const scrollToBottom = (element) => 
element.scrollIntoView({ behavior: "smooth", block: "end" });

检测元素是否在屏幕中

const callback = (entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      // `entry.target` is the dom element
      console.log(`${entry.target.id} is visible`);
    }
  });
};

const options = {
  threshold: 1.0,
};
const observer = new IntersectionObserver(callback, options);
const btn = document.getElementById("btn");
const bottomBtn = document.getElementById("bottom-btn");
observer.observe(btn);
observer.observe(bottomBtn);

检测设备

使用 navigator.userAgent 来检测网站运行在哪种平台设备上。

const detectDeviceType = () =>
  /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
    navigator.userAgent
  ) ? "Mobile" : "Desktop";
console.log(detectDeviceType());

隐藏元素

我们可以将元素的 style.visibility 设置为 hidden,隐藏元素的可见性,但元素的空间仍然会被占用。如果设置元素的 style.display 为 none,会将元素从渲染流中删除。

const hideElement = (el, removeFromFlow = false) => {
  removeFromFlow ? (el.style.display = 'none')
  : (el.style.visibility = 'hidden')
}

等待函数

JavaScript 提供了 setTimeout 函数,但是它并不返回 Promise 对象,所以我们没办法使用 async 作用在这个函数上,但是我们可以封装等待函数。

const wait = (ms) => new Promise((resolve)=> setTimeout(resolve, ms))

const asyncFn = async () => {
  await wait(1000)
  console.log('等待异步函数执行结束')
}

asyncFn()

results matching ""

    No results matching ""