值得一看的前端代码片段

摘要

在日常的开发过程中,我们都会有一些常用的代码片段,这些代码片段可以直接复制到各个项目中使用,非常方便。如果你有接手过别人的项目,就可以很明显感受到几个项目一般都会有一些相同的工具类方法,这些方法就是之前开发者的常用代码片段。

现在前端社区相当完善,有许多好用质量又有保证的库,如 lodash、dayjs、classnames、js-cookie 等,这些库基本能满足你开发中对数组、日期、类名、cookie 等的处理。

 检测元素之外的点击

在实现隐藏弹窗或收起下拉框时,如果你还在一层层判断是否点击了某个元素之外的区域,赶紧试试使用 contains 方法来实现。

document.addEventListener('click', function (evt) {
    // isClickedOutside 为 true 如果点击的元素在 ele 之外
    const isClickedOutside = !ele.contains(evt.target);
});

快速打开官网

当你想查看第三方库的主页和代码仓库时,你可以使用一下命令快速打开:

// 打开主页
npm home PACKAGE_NAME
npm home react

// 打开代码仓库
npm repo PACKAGE_NAME
npm repo react

一次性的事件监听

除了在监听的事件函数中移除当前的监听外,也可以使用 once 参数。

const handler = function (e) {};
ele.addEventListener('event-name', handler, { once: true });

格式化时分秒

在展示音视频时长之类的场景时,需要把时长秒数格式为 HH:mm:ss 的格式。

const formatSeconds = (s) =>
  [parseInt(s / 60 / 60), parseInt((s / 60) % 60), parseInt(s % 60)]
    .join(':')
    .replace(/\b(\d)\b/g, '0$1')

URL 参数转化为对象

获取 url 参数有个热门的库 query-string,如果不想使用的话,可以通过 URLSearchParams API 实现。

const getUrlParams = (query) =>
  Array.from(new URLSearchParams(query)).reduce(
    (p, [k, v]) =>
      Object.assign({}, p, { [k]: p[k] ? (Array.isArray(p[k]) ? p[k] : [p[k]]).concat(v) : v }),
    {}
  )
  
// 获取 query 参数
getUrlParams(location.query)
// { a: ['1', '4'], b: '2', c: '3' }
getUrlParams('?a=1&b=2&c=3&a=4')

// 获取 hash 参数
getUrlParams(location.hash.split('?')[1])

显示上传的图片

通过 fileReader API 的 readAsDataURL 方法来显示上传图片

function readImage() {
  const fileReader = new FileReader()
  const file = document.getElementById('uploaded-file').files[0]

  if (file) {
    fileReader.readAsDataURL(file)
  }

  fileReader.addEventListener(
    'load',
    () => {
      const result = fileReader.result
      const resultContainer = document.getElementById('result')
      const img = document.createElement('img')
      img.src = result
      resultContainer.append(img)
    },
    { once: true }
  )
}

文件下载

使用 a 标签的 download 属性,同源才能触发下载,IE 不支持,移动端兼容性也不太好。

<a href="/path/to/file" download>Download</a>

// 或者 js 临时生成 a
function download(url) {
  const link = document.createElement('a')
  link.download = 'file name'
  link.href = url

  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

多行省略号

单行或多行截断显示省略号,很常用的 CSS 片段。

.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.truncate {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

滚动条样式

自定义滚动条样式也是很常见的需求,除了通过样式,也可以通过第三方库(如 better-scroll 等)来实现自定义滚动条样式。

/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

/*定义滚动条轨道 内阴影+圆角*/
::-webkit-scrollbar-track {
  border-radius: 10px;
  background-color: #fafafa;
}

/*定义滑块 内阴影+圆角*/
::-webkit-scrollbar-thumb {
  border-radius: 10px;
  background: rgb(191, 191, 191);
}

// 较新的 API
body {
  scrollbar-width: thin;
  scrollbar-color: #718096 #edf2f7;
}

限制并发

当有大量请求需要发起时,往往需求限制并发数量保证其他请求能优先返回。

async function asyncPool(poolLimit, iterable, iteratorFn) {
  // 用于保存所有异步请求
  const ret = [];
  // 用户保存正在进行的请求
  const executing = new Set();
  for (const item of iterable) {
    // 构造出请求 Promise
    const p = Promise.resolve().then(() => iteratorFn(item, iterable));
    ret.push(p);
    executing.add(p);
    // 请求执行结束后从正在进行的数组中移除
    const clean = () => executing.delete(p);
    p.then(clean).catch(clean);
    // 如果正在执行的请求数大于并发数,就使用 Promise.race 等待一个最快执行完的请求
    if (executing.size >= poolLimit) {
      await Promise.race(executing);
    }
  }
  // 返回所有结果
  return Promise.all(ret);
}

// 使用方法
const timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i));
asyncPool(2, [1000, 5000, 3000, 2000], timeout).then(results => {
  console.log(results)
})

 uuid

生成 uuid 的代码片段

const uuid = (a) =>
  a
    ? (a ^ ((Math.random() * 16) >> (a / 4))).toString(16)
    : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zqwang888

一毛不嫌少,一块不嫌多!

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

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

打赏作者

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

抵扣说明:

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

余额充值