前端必備:一套通用的 JS 復(fù)制功能(保留/去掉換行,兼容 PC/移動(dòng)端/微信)
前言
在前端開(kāi)發(fā)中,我們經(jīng)常會(huì)遇到“復(fù)制文本到剪貼板”的需求,比如復(fù)制賬號(hào)、復(fù)制表格數(shù)據(jù)、批量復(fù)制命令等。
然而,很多同學(xué)寫(xiě)的復(fù)制功能:
- 有時(shí)候粘貼出來(lái)?yè)Q行沒(méi)了
- 有時(shí)候在移動(dòng)端、微信內(nèi)置瀏覽器里完全沒(méi)反應(yīng)
- 復(fù)制長(zhǎng)文本時(shí)被截?cái)?/li>
本文給大家?guī)?lái)一份終極通用版復(fù)制方法,支持:
? 保留換行 / 去掉換行
? 兼容 PC / 移動(dòng)端 / 微信內(nèi)置瀏覽器 / 支付寶 WebView
? 支持超長(zhǎng)文本
? 帶成功/失敗回調(diào),方便 UI 提示
? 不污染頁(yè)面,不會(huì)觸發(fā)滾動(dòng)
復(fù)制方法實(shí)現(xiàn)
/**
* 通用復(fù)制方法
* @param {string} value 要復(fù)制的文本
* @param {Object} options 額外配置
* @param {boolean} options.keepLineBreak 是否保留換行(默認(rèn) true)
* @param {Function} options.onSuccess 復(fù)制成功回調(diào)
* @param {Function} options.onError 復(fù)制失敗回調(diào)
*/
function copyFn(value, {
keepLineBreak = true,
onSuccess = () => {},
onError = () => {}
} = {}) {
try {
// 創(chuàng)建元素(textarea 支持換行,input 只能單行)
const el = keepLineBreak ? document.createElement("textarea") : document.createElement("input");
// 設(shè)置文本,去掉換行時(shí)替換為一個(gè)空格
el.value = keepLineBreak ? value : value.replace(/\n/g, ' ');
// 防止頁(yè)面滾動(dòng)閃動(dòng)
el.style.position = "fixed";
el.style.top = "-9999px";
el.style.left = "-9999px";
el.style.opacity = "0";
document.body.appendChild(el);
el.select();
el.setSelectionRange(0, el.value.length); // 移動(dòng)端兼容
const success = document.execCommand("copy");
document.body.removeChild(el);
if (success) {
onSuccess();
} else {
throw new Error("復(fù)制命令返回 false");
}
} catch (err) {
console.error("復(fù)制失敗:", err);
onError(err);
}
}
使用示例
- 保留換行
let text1 = '';
for (let i = 0; i < 5; i++) {
text1 += `行 ${i + 1}: Hello World\n`;
}
copyFn(text1, {
keepLineBreak: true,
onSuccess: () => console.log("復(fù)制成功(帶換行)"),
onError: (err) => console.error(err)
});
粘貼結(jié)果:
行 1: Hello World
行 2: Hello World
行 3: Hello World
行 4: Hello World
行 5: Hello World
- 去掉換行
let text2 = '';
for (let i = 0; i < 5; i++) {
text2 += `行 ${i + 1}: Hello World\n`;
}
copyFn(text2, {
keepLineBreak: false,
onSuccess: () => console.log("復(fù)制成功(無(wú)換行)")
});
粘貼結(jié)果:
行 1: Hello World 行 2: Hello World 行 3: Hello World 行 4: Hello World 行 5: Hello World
兼容性分析
- PC 瀏覽器:完美兼容(Chrome / Edge / Firefox / Safari / IE 10+)
- 移動(dòng)端瀏覽器:兼容安卓、iOS
- 微信 / 支付寶內(nèi)置瀏覽器:可用
- 超長(zhǎng)文本:使用 textarea 可支持大文本復(fù)制,不會(huì)被截?cái)?/li>
進(jìn)階優(yōu)化
為了提升成功率,可以在新瀏覽器上優(yōu)先使用 navigator.clipboard.writeText,老瀏覽器再回退到 execCommand,這樣能做到幾乎 100% 復(fù)制成功。
可升級(jí)版本示例:
async function smartCopy(text) {
try {
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(text);
console.log("復(fù)制成功(Clipboard API)");
} else {
copyFn(text);
}
} catch (err) {
console.error("復(fù)制失敗:", err);
}
}
總結(jié)
本文給大家封裝的 copyFn 方法:
一行代碼搞定復(fù)制功能
保留換行 / 去掉換行隨意切換
兼容各種復(fù)雜環(huán)境
可擴(kuò)展成 Clipboard API 雙引擎版本
復(fù)制功能雖小,但在實(shí)際業(yè)務(wù)中用得很頻繁,封裝好一套穩(wěn)定的工具函數(shù),可以讓你的項(xiàng)目更健壯、更好維護(hù)。
?? 你在項(xiàng)目中還遇到過(guò)哪些復(fù)制相關(guān)的坑?歡迎評(píng)論區(qū)交流~