原生JS實現貼上到剪貼簿

Lazy發表於2018-03-05

本文主要討論原生方法

目前常見的實現貼上到剪貼簿主要有以下兩種方法:

  • 第三方庫 clipboard
  • 原生JS, 主要是 document.execCommand方法

第一種方法按照文件說明,設定觸發元素的data-clipboard-text 或者 data-clipboard-target即可,不做說明,詳見文件

第二種方法: document.execCommand

這個方法的相容性其實不算很好,特別是移動端,具體這裡有, 但clipboard針對部分機型也有問題,所以具體使用還是得看情況, 因此使用該方法前檢查瀏覽器是否支援很有必要bool = document.execCommand('copy')

MDN對上述方法的解釋如下:

當一個HTML文件切換到設計模式 designMode時,文件物件暴露 execCommand 方法,該方法允許執行命令來操縱可編輯區域的內容。

注意加粗部分,設計模式 ,即:使用前我們需切換文件模式為設計模式

document.designMode = 'on'
複製程式碼

完成執行命令之後再設定值為off

還有個加粗部分,可編輯區域 ,預設的input和textarea元素是可編輯(設定一個元素的contenteditable="true"也可啟用元素的編輯模式)

先來看錶單元素如何實現

ele.addEventListener('click', () => {
    document.designMode = 'on'
    let bool = document.execCommand('copy')
    if (!bool) {
        alert('sorry, 手動複製吧')
    } else {
        let val = 'something'
        let inputEle = document.createElement('input')
        document.body.appendChild(inputEle)
        inputEle.setAttribute('value', val)
        inputEle.setAttribute('readonly', 'readonly')
        inputEle.select()
        document.execCommand('copy')
        document.body.removeChild(inputEle)
        alert('copied')
    }
    document.designMode = 'off'
})
複製程式碼

為避免出現游標或者拉起輸入法,需要給元素設定readonly屬性

inputEle.select()方法在一些瀏覽器中有時不能選中所有內容,這時需要利用inputeElement的setSelectionRange方法:

HTMLInputElement.setSelectionRange 方法可以從一個被 focused 的 input 元素中選中特定範圍的內容。

綜上加兩行:

...
inputEle.focus()
inputEle.setSelectionRange(0, inputEle.value.length)
document.execCommand('copy')
...
複製程式碼

如果不是input等表單元素,不能使用selectsetSelectRange的話,那麼我們可以使用getSelectioncreateRange方法來模擬這個過程了,Selection物件表示使用者選擇的文字範圍或游標的當前位置,滿足執行execComman命令的可編輯活動區域,如下

let range = document.createRange()
let tar = document.querySelector('#code')
range.selectNodeContents(tar)
let selection = window.getSelection()
selection.removeAllRanges()
selection.addRange(range)
document.execCommand('copy')
selection.removeAllRanges()
複製程式碼

上述針對非input,textarea等表單元素也能實現了

相關文章