2019年2月10日

如何用 Javascript 複製文字﹍跨瀏覽器相容 iOS

如何用 Javascript 複製文字﹍跨瀏覽器相容 iOS

Wayne Fu 0 A+
最近接到的需求類似「點擊按鈕後自動複製折價券代碼」這樣的功能,因此研究了一下如何實現前端利用 Javascript 複製文字。

多年前曾在「如何用語法保護網頁文章著作權」多篇系列文寫相關功能,但這些年網頁技術進展很快,HTML5 新的 api 讓複製文字變得相當簡單。

過去網頁前端的大魔王是 IE,為了 IE 的相容性得傷透腦筋,然而隨著 IE 的式微,取而代之的是另一個大魔王 iOS,蘋果裝置的諸多限制讓 JS 複製文字異常難解,因此本篇詳細研究該如何跨瀏覽器、跨平台相容 JS 複製文字的問題。



一、Javascript 複製文字的進程


以前網頁用 JS 複製文字很困難,必須用 Flash 繞過瀏覽器的限制,可參考這篇「點選自動複製 ( ZeroClipboard )」,缺點是瀏覽器的 Flash 功能被關閉就無效。

後來 HTML 5 新增了「Clipboard API」,可直接存取剪貼簿的資料,真的方便許多,但缺點是蘋果 iOS 裝置不支援。

所以這件事要做到跨裝置、瀏覽器支援,一方面可使用 Clipboard API,一方面需要單獨對 iOS 裝置進行處理。



二、iOS 的限制


這個討論串「Copy to clipboard using Javascript in iOS」對 iOS 的狀況說明的很詳細,摘錄重點如下:

  • iOS 版本 > 10 的時候:
    • 只有 input、textarea 這兩個元素的文字可以複製
    • 這兩個元素的屬性必須是可以編輯(contenteditable)、不能是只讀狀態(readonly)
    • 這兩個元素內的文字必須是選取狀態才能複製
    • 符合以上條件後,即可使用 Clipboard API
  • iOS 版本 < 10 的時候:
    • Safari 有些限制,只能經由 "點擊" 這個動作來觸發複製文字的程式碼
    • 意思就是無法偷偷在背景自動執行程式來複製文字


另外 iOS 裝置用 JS 執行複製文字時,上還有些不太好的效果,例如:

  • 可能會彈出鍵盤
  • 螢幕會捲動到要複製文字的 input、textarea 位置



三、範例程式碼


有國外高手寫了「clipboard.js」解決複製文字的問題,那麼開頭提到的「點擊按鈕後自動複製折價券代碼」這個功能,根據以上相關資訊進行修改後,提供範例程式碼如下:

<input value="填入要複製的字串 例如 123456" style="display:none;"/><button class="copy_coupon">【123456】點擊複製數字</button>

<script src='//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js'></script>
<script>
window.Clipboard = (function(window, document, navigator) {
var textArea,
copy;

function isOS() {
return navigator.userAgent.match(/ipad|iphone/i);
}

function createTextArea(text) {
textArea = document.createElement('textArea');
textArea.value = text;
document.body.appendChild(textArea);
}

function selectText() {
var range,
selection;

if (isOS()) {
range = document.createRange();
range.selectNodeContents(textArea);
selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
textArea.setSelectionRange(0, 999999);
} else {
textArea.select();
}
}

function copyToClipboard() {
document.execCommand("Copy");
document.body.removeChild(textArea);
}

copy = function(text) {
createTextArea(text);
selectText();
copyToClipboard();
};

return {
copy: copy
};
})(window, document, navigator);

$(".copy_coupon").on("click", function() {
var $this = $(this),
value = $this.prev("input").val();
window.Clipboard.copy(value);
});
</script>

範例程式碼的效果,如同下面這個按鈕,複製後會自動複製數字 123456,可自行測試:








四、補充


若在 iOS 進行複製,會發現如前所述,螢幕自動捲到下方,因為這個用來暫時存放複製文字的 textarea 元素,預設放在 body 的最後面,當 iOS 進行選取的動作時,游標就會自動移動到頁尾。

要解決這個問題,需要在觸發 click 的程式碼最後面,例如在 window.Clipboard.copy(value); 的下一行,加入以下程式碼,計算按鈕元素的座標,強制螢幕捲回按鈕的位置:

$("html, body").scrollTop($this.offset().top)


更多 Javascript 相關技巧:
0 0
如這篇文章對你有幫助,歡迎「分享」到 FB、「追蹤」粉絲團、「訂閱」最新文章

1 則留言:

張貼留言注意事項:

◎ 勾選「通知我」可收到後續回覆的mail!
◎ 請在相關文章留言,與文章無關的主題可至「Blogger 社團」提問。
◎ 提問若無法提供足夠的資訊供判斷,可能會被無視。建議先參考這篇「Blogger 提問技巧及注意事項」。
◎ CSS 相關問題非免費諮詢,建議使用「Chrome 開發人員工具」尋找答案。
◎ 手機版相關問題請參考「Blogger 行動版範本的特質」→「三、行動版範本不一定能執行網頁版工具」。
◎ 非官方範本問題、或貴站為商業網站,請參考「Blogger 免費諮詢 + 付費諮詢
◎ 若是使用官方 RWD 範本,請參考「Blogger 推出全新自適應 RWD 官方範本及佈景主題」→ 不建議對範本進行修改!
◎ 若留言要輸入語法,"<"、">"這兩個符號請用其他符號代替,否則語法會消失!
◎ 為了過濾垃圾留言,所有留言不會即時發佈,請稍待片刻。
◎ 本站「已關閉自刪留言功能」。

TOP