好用的JS代码片段

204 阅读2分钟

今天在逛 github 的时候,无意中找到一个网站,里面有很多常用功能的代码片段,下面是我在网站看到的几个好用的代码片段。链接我放到了文章结尾,想看链接的可以直接跳到最后。

获取url中携带的参数和值

const getURLParameters = url =>
  (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
    (a, v) => (
      (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a
    ),
    {}
  );

getURLParameters('baidu.com'); // {}
getURLParameters('http://baidu.com/page?name=kobe&age=24');
// {name: 'kobe', age: '24'}

获取当前设备类型

使用 navigator.userAgent 属性来区分当前用户设备类型

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

复制到剪贴板

const copyToClipboard = str => {
  // 创建一个 textarea 元素,用来存放要复制的文本信息
  const el = document.createElement('textarea');
  el.value = str;
  el.setAttribute('readonly', '');
  el.style.position = 'absolute';
  el.style.left = '-9999px';
  document.body.appendChild(el);
  // 使用Selection.getRangeAt()存储选中的文本
  const selected =
    document.getSelection().rangeCount > 0
      ? document.getSelection().getRangeAt(0)
      : false;
  el.select();
  // 调用 document.execCommand('copy') 命令复制到剪贴板 
  document.execCommand('copy');
  // 删除 textarea 元素
  document.body.removeChild(el);
  if (selected) {
    // 使用 getSelection().addRange()恢复原始选定范围
    document.getSelection().removeAllRanges();
    document.getSelection().addRange(selected);
  }
};

copyToClipboard('copy success'); // 'copy success' copied to clipboard.

用户停止滚动时执行回调函数

const onScrollStop = callback => {
  let isScrolling;
  // 监听用户滚动事件
  window.addEventListener(
    'scroll',
    e => {
      clearTimeout(isScrolling);
      // 150 毫秒内未滚动则执行回调
      isScrolling = setTimeout(() => {
        callback();
      }, 150);
    },
    false
  );
};

onScrollStop(() => {
  console.log('The user stopped scrolling');
});

提示用户 Caps Lock 键是否打开

通常用于用户输入账号密码时对用户进行提示

<form>
  <label for="username">Username:</label>
  <input id="username" name="username">

  <label for="password">Password:</label>
  <input id="password" name="password" type="password">
  <span id="password-message" style="display: none">Caps Lock is on</span>
</form>
const el = document.getElementById('password');
const msg = document.getElementById('password-message');

el.addEventListener('keyup', e => {
  // 使用 getModifierState() 获取按键当前的状态
  msg.style = e.getModifierState('CapsLock')
    ? 'display: block'
    : 'display: none';
});

深合并

合并两个对象

  1. 使用Object.keys() 获取两个对象中的键,使用 new Set() 合并两个对象的键
  2. 使用 Array.reduce() 将合并后的唯一键添加到对象
const deepMerge = (a, b, fn) =>
  [...new Set([...Object.keys(a), ...Object.keys(b)])].reduce(
    (acc, key) => ({ ...acc, [key]: fn(key, a[key], b[key]) }),
    {}
  );


deepMerge(
  { a: true, b: { c: [1, 2, 3] } },
  { a: false, b: { d: [1, 2, 3] } },
  (key, a, b) => (key === 'a' ? a && b : Object.assign({}, a, b))
);
// { a: false, b: { c: [ 1, 2, 3 ], d: [ 1, 2, 3 ] } }

如何在JS中实现睡眠功能

同步版本

const sleepSync = (ms) => {
  const end = new Date().getTime() + ms;
  while (new Date().getTime() < end) { /* do nothing */ }
}

const printNums = () => {
  console.log(1);
  sleepSync(500);
  console.log(2);
  console.log(3);
};

printNums(); // Logs: 1, 2, 3 (2 and 3 log after 500ms)

异步版本

const sleep = (ms) =>
  new Promise(resolve => setTimeout(resolve, ms));

const printNums = async() => {
  console.log(1);
  await sleep(500);
  console.log(2);
  console.log(3);
};

printNums(); // Logs: 1, 2, 3 (2 and 3 log after 500ms)

如果大家还有其他想要了解的代码片段,可以去网站去查找(www.30secondsofcode.org/),可以直接进行搜索,里面有很多简短代码段,非常值得学习!