?
在 Web 開發(fā)領(lǐng)域,開發(fā)效率是關(guān)鍵。為什么每次開始新項(xiàng)目時(shí)都要重新發(fā)明輪子?今天,本文匯總整理了一些方便日常開發(fā)使用的 JavaScript 代碼片段,超越了 Lodash 和 day.js 等常見代碼片段,提升你的開發(fā)效率,減少工作時(shí)長。
讓我們開始吧!
1. 檢測元素外的點(diǎn)擊
厭倦了復(fù)雜的檢查以查看點(diǎn)擊是否落在目標(biāo)元素之外?使用 contains 方法簡化事情,以更簡潔的方式隱藏模式或折疊菜單:
document.addEventListener('click', function (evt) {
// isClickedOutside is true if the clicked element is outside 'ele'
const isClickedOutside = !ele.contains(evt.target);
});
2. 快速打開官方網(wǎng)站
需要查閱第三方庫的文檔或存儲庫?這些命令將快速帶您到達(dá)那里:
# Open the homepage
npm home PACKAGE_NAME
npm home react
# Open the repository
npm repo PACKAGE_NAME
npm repo react
3. 一次性事件監(jiān)聽器
對于只想處理一次的事件,可以利用 once 選項(xiàng),而不是手動(dòng)刪除監(jiān)聽器:
const handler = function (e) {};
ele.addEventListener('event-name', handler, { once: true });
4. 將秒數(shù)格式化為 HH:mm:ss
顯示音頻或視頻的時(shí)長時(shí),以用戶友好的 HH:mm:ss 格式顯示秒數(shù):
const formatSeconds = (s) =>
[parseInt(s / 60 / 60), parseInt((s / 60) % 60), parseInt(s % 60)]
.join(':')
.replace(/\b(\d)\b/g, '0$1')
對于相對時(shí)間顯示,如“幾秒前”或“5 分鐘前”,請?zhí)剿?timeago.js 庫!
5. 將 URL 參數(shù)轉(zhuǎn)換為對象
雖然 query-string 是一個(gè)流行的庫,但可以直接使用 URLSearchParams API 實(shí)現(xiàn)相同的功能:
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 parameters
getUrlParams(location.query)
// { a: ['1', '4'], b: '2', c: '3' }
getUrlParams('?a=1&b=2&c=3&a=4')
// Get hash parameters
getUrlParams(location.hash.split('?')[1])
6. 安全打開新標(biāo)簽頁
打開新標(biāo)簽頁看似微不足道,但需要注意安全。在外部鏈接時(shí),使用 noopener noreferrer 來防止惡意網(wǎng)站通過 window.opener.location 重定向您的網(wǎng)站。這同樣適用于 window.open。
<a target="_blank" rel="noopener noreferrer">...</a>
// window.open defaults rel to 'opener', so set it explicitly
window.open('https://google.com', 'google', 'noopener,noreferrer')
警告:以下代碼片段存在安全漏洞!
<a target="_blank" rel="opener">
...</a>
window.opener.location = 'http://fake.website.here';
7. 預(yù)覽上傳的圖像
使用 FileReader API 直接在瀏覽器中顯示用戶上傳圖像的預(yù)覽:
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 }
)
}
8. 下載文件
使用 <a> 標(biāo)簽的下載屬性觸發(fā)下載。請記住,這對于同源文件可靠地起作用,并且在 IE 和移動(dòng)設(shè)備上可能會受到限制:
<a href="/path/to/file" download>Download</a>
或者,使用 JavaScript 生成臨時(shí)的 <a> 標(biāo)簽:
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)
}
對于靜態(tài)文件,在服務(wù)器上設(shè)置適當(dāng)?shù)?Content-Disposition 標(biāo)頭也可以觸發(fā)下載:
Content-Disposition: attachment; filename="filename.jpg"
除了文件下載之外,還可以使用 Blob 對象和 createObjectURL 方法創(chuàng)建和下載文本或 JSON 文件:
const data = JSON.stringify({ 'message': 'Hello Word' });
const blob = new Blob([data], { type: 'application/json' });
// Create a URL for the blob
const url = window.URL.createObjectURL(blob);
// Download the URL using the 'download' function above
...
// Release the URL object
window.URL.revokeObjectURL(url);
9. 記憶函數(shù)結(jié)果
使用記憶法緩存計(jì)算量大的函數(shù)的結(jié)果:
const memoize = (fn) =>
(
(cache = Object.create(null)) =>
(arg) =>
cache[arg] || (cache[arg] = fn(arg))
)()
10. 多行省略號...
使用 CSS 用省略號截?cái)辔谋緝?nèi)容,無論是單行還是多行:
.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 個(gè)元素
使用 CSS 選擇器定位列表中的最后幾個(gè)元素:
// First three items
li:nth-child(-n + 3) {
text-decoration: underline;
}
// Items 2 through 5
li:nth-child(n + 2):nth-child(-n + 5) {
color: #2563eb;
}
// Last two items
li:nth-last-child(-n + 2) {
text-decoration: line-through;
}
12. 自定義滾動(dòng)條樣式
增強(qiáng)滾動(dòng)條的外觀和感覺:
::-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;
}
請記住,滾動(dòng)條樣式也可以使用 better-scroll 等庫來實(shí)現(xiàn)更高級的自定義。
13. 使用最大余數(shù)法精確計(jì)算百分比
使用百分比時(shí),四舍五入有時(shí)會導(dǎo)致總數(shù)不完全等于 100%。使用最大余數(shù)法進(jìn)行準(zhǔn)確分配:
// 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 * digits
let currentSeats = votesPerQuota.reduce((total, cur) => total + Math.floor(cur), 0)
while(totalSeats - currentSeats > 0) {
let maxIdx = -1
let maxValue = Number.NEGATIVE_INFINITY
for(let i = 0; i < remainder.length; i++) {
if (maxValue < remainder[i]) {
maxValue = remainder[i]
maxIdx = i
}
}
seats[maxIdx]++
remainder[maxIdx] = 0
currentSeats++
}
return seats.map((val) => `${val / totalSeats * 100}%`)
}
14. 限制并發(fā)請求
處理大量請求時(shí),管理并發(fā)以防止服務(wù)器不堪重負(fù):
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 usage
const timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i));
asyncPool(2, [1000, 5000, 3000, 2000], timeout).then(results => {
console.log(results)
})
15. 生成 UUID
創(chuàng)建通用唯一標(biāo)識符:
const uuid = (a) =>
a
? (a ^ ((Math.random() * 16) >> (a / 4))).toString(16)
: ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid)
16. 在模態(tài)框打開時(shí)禁用正文滾動(dòng)
在模態(tài)框打開時(shí)防止背景內(nèi)容滾動(dòng):
// Disable body scrolling
document.body.style.overflow = 'hidden';
// Re-enable scrolling
document.body.style.removeProperty('overflow');
總結(jié)
以上就是我今天想與你分享的16個(gè)日常開發(fā)中會經(jīng)常遇到的一些功能需求,希望通過閱讀本文內(nèi)容能夠?qū)δ阌兴鶐椭?,如果你還有其他問題,請?jiān)诹粞詤^(qū)給我留言,我們一起交流學(xué)習(xí)進(jìn)步。
最后,感謝你的閱讀,祝編程愉快。
該文章在 2024/10/14 10:54:41 編輯過