前端日常开发必备16 个JavaScript 代码片段记录
来源:web前端开发。
汇总整理了一些方便日常开发使用的 JavaScript 代码片段,超越了 Lodash 和 day.js 等常见代码片段,提升你的开发效率,减少工作时长。
让我们开始吧!
1. 检测元素外的点击
厌倦了复杂的检查以查看点击是否落在目标元素之外?使用 contains 方法简化事情,以更简洁的方式隐藏模式或折叠菜单:
document.addEventListener('click', function (evt) {// isClickedOutside is true if the clicked element is outside 'ele'const isClickedOutside = !ele.contains(evt.target);});
2. 快速打开官方网站
需要查阅第三方库的文档或存储库?这些命令将快速带您到达那里:
# Open the homepagenpm home PACKAGE_NAMEnpm home react# Open the repositorynpm repo PACKAGE_NAMEnpm repo react
3. 一次性事件监听器
对于只想处理一次的事件,可以利用 once 选项,而不是手动删除监听器:
const handler = function (e) {};ele.addEventListener('event-name', handler, { once: true });
4. 将秒数格式化为 HH:mm:ss
显示音频或视频的时长时,以用户友好的 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')
对于相对时间显示,如“几秒前”或“5 分钟前”,请探索 timeago.js 库!
5. 将 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 }),{})// Get query parametersgetUrlParams(location.query)// { a: ['1', '4'], b: '2', c: '3' }getUrlParams('?a=1&b=2&c=3&a=4')// Get hash parametersgetUrlParams(location.hash.split('?')[1])
6. 安全打开新标签页
打开新标签页看似微不足道,但需要注意安全。在外部链接时,使用 noopener noreferrer 来防止恶意网站通过 window.opener.location 重定向您的网站。这同样适用于 window.open。
<a target="_blank" rel="noopener noreferrer">...</a>// window.open defaults rel to 'opener', so set it explicitlywindow.open('https://google.com', 'google', 'noopener,noreferrer')
警告:以下代码片段存在安全漏洞!
<a target="_blank" rel="opener">...</a>window.opener.location = 'http://fake.website.here';
7. 预览上传的图像
使用 FileReader API 直接在浏览器中显示用户上传图像的预览:
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.resultconst resultContainer = document.getElementById('result')const img = document.createElement('img')img.src = resultresultContainer.append(img)},{ once: true })}
8. 下载文件
使用 <a> 标签的下载属性触发下载。请记住,这对于同源文件可靠地起作用,并且在 IE 和移动设备上可能会受到限制:
<a href="/path/to/file" download>Download</a>
或者,使用 JavaScript 生成临时的 <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)}
对于静态文件,在服务器上设置适当的 Content-Disposition 标头也可以触发下载:
Content-Disposition: attachment; filename="filename.jpg"
除了文件下载之外,还可以使用 Blob 对象和 createObjectURL 方法创建和下载文本或 JSON 文件:
const data = JSON.stringify({ 'message': 'Hello Word' });const blob = new Blob([data], { type: 'application/json' });// Create a URL for the blobconst url = window.URL.createObjectURL(blob);// Download the URL using the 'download' function above...// Release the URL objectwindow.URL.revokeObjectURL(url);
9. 记忆函数结果
使用记忆法缓存计算量大的函数的结果:
const memoize = (fn) =>((cache = Object.create(null)) =>(arg) =>cache[arg] || (cache[arg] = fn(arg)))()
10. 多行省略号...
使用 CSS 用省略号截断文本内容,无论是单行还是多行:
.truncate {overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}.truncate-multi {display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2;overflow: hidden;}
11. 使用 CSS 选择最后 N 个元素
使用 CSS 选择器定位列表中的最后几个元素:
// First three itemsli:nth-child(-n + 3) {text-decoration: underline;}// Items 2 through 5li:nth-child(n + 2):nth-child(-n + 5) {color:}// Last two itemsli:nth-last-child(-n + 2) {text-decoration: line-through;}

12. 自定义滚动条样式
增强滚动条的外观和感觉:
::-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);}/* Modern scrollbar API */body {scrollbar-width: thin;scrollbar-color: #718096 #edf2f7;}
请记住,滚动条样式也可以使用 better-scroll 等库来实现更高级的自定义。
13. 使用最大余数法精确计算百分比
使用百分比时,四舍五入有时会导致总数不完全等于 100%。使用最大余数法进行准确分配:
// Outputs: ['32.56%', '6.97%', '27.91%', '32.56%']getPercentWithPrecision([56, 12, 48, 56], 2)function getPercentWithPrecision(valueList, precision) {const digits = Math.pow(10, precision)const sum = valueList.reduce((total, cur) => total + cur, 0)const votesPerQuota = valueList.map((val) => {return val / sum * 100 * digits})const seats = votesPerQuota.map((val) => {return Math.floor(val);});const remainder = votesPerQuota.map((val) => {return val - Math.floor(val)})let totalSeats = 100 * digitslet currentSeats = votesPerQuota.reduce((total, cur) => total + Math.floor(cur), 0)while(totalSeats - currentSeats > 0) {let maxIdx = -1let maxValue = Number.NEGATIVE_INFINITYfor(let i = 0; i < remainder.length; i++) {if (maxValue < remainder[i]) {maxValue = remainder[i]maxIdx = i}}seats[maxIdx]++remainder[maxIdx] = 0currentSeats++}return seats.map((val) => `${val / totalSeats * 100}%`)}
14. 限制并发请求
处理大量请求时,管理并发以防止服务器不堪重负:
async function asyncPool(poolLimit, iterable, iteratorFn) {const ret = [];const executing = new Set();for (const item of iterable) {const p = Promise.resolve().then(() => iteratorFn(item, iterable));ret.push(p);executing.add(p);const clean = () => executing.delete(p);p.then(clean).catch(clean);if (executing.size >= poolLimit) {await Promise.race(executing);}}return Promise.all(ret);}// Example usageconst timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i));asyncPool(2, [1000, 5000, 3000, 2000], timeout).then(results => {console.log(results)})
15. 生成 UUID
创建通用唯一标识符:
const uuid = (a) =>a? (a ^ ((Math.random() * 16) >> (a / 4))).toString(16): ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid)
16. 在模态框打开时禁用正文滚动
在模态框打开时防止背景内容滚动:
// Disable body scrollingdocument.body.style.overflow = 'hidden';// Re-enable scrollingdocument.body.style.removeProperty('overflow');






