一套通用的 JS 復(fù)制功能(保留/去掉換行,兼容 PC/移動(dòng)端/微信)

前端必備:一套通用的 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);
  }
}

使用示例

  1. 保留換行
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
  1. 去掉換行
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ū)交流~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容