前端模擬用戶的複製操做

1、前言

  用戶在瀏覽網頁的過程當中,執行復制操做的場景是很是多的,例如:複製連接地址、複製分享文案等等。前端

  而前端經過模擬用戶的複製操做,能夠減小操做的步驟,進而優化用戶體驗。git

  複製操做主要分爲如下兩部分:github

  • 選中文本:對應用戶經過鼠標或者觸屏選中文本的操做。
  • 操做系統剪貼板:對應用戶按下 Ctrl(command) + C 的操做。

2、選中文本

  首先,讀者須要明白,不是全部的文本均可以被選中的(後續會提到),筆者這裏先介紹幾個能夠選中文本的狀況:瀏覽器

一、input 和 textarea

  因爲 input 元素的工做方式因其類型屬性的值而有很大的差別,因此這裏只討論 text 的狀況。app

  由於 JavaScript 提供了 HTTMLInputElement.select() 方法,因此選中 textarea 和 input 中的內容就變得很是簡單:post

document.querySelector('input').select()
複製代碼

  若是 input 和 textarea 元素附加了 disabled 屬性,那麼其內容是沒法被選中的,這種狀況最好是將 disabled 替換爲 readonly 。優化

二、div

  div 元素並無開箱即用的 select() 方法,這就須要讀者瞭解一個新的對象: Selection 。ui

  Selection 對象表示用戶選擇文本的範圍以及光標的範圍。關於 Selection 對象,讀者須要瞭解如下幾個術語:spa

  • 錨點:選區的起始點。
  • 焦點:選區的終止點。
  • 範圍:文檔中連續的一部分。

  與 Selection 對象息息相關的還有一個 Range 對象,它主要用來自定義選區。對於這兩個對象不瞭解的讀者,能夠查看文末給出的參考文獻,接下來,利用 Selection 和 Range 對象實現上述 select() 方法:操作系統

function select (element) {
    const selection = window.getSelection()
    const range = document.createRange()
    range.selectNodeContents(element)
    selection.removeAllRanges()
    selection.addRange(range)
  }
複製代碼

3、操做系統剪貼板

  document 暴露的 execCommand 方法,能夠用來運行操做系統提供的命令,而且這些命令大部分做用於 Selection 對象。

  該方法返回的布爾值表示操做是否被支持或者是否被啓用,可是調用一個命令以前,不能嘗試使用返回值去校驗瀏覽器的兼容性。

function copyText () {
    let success = true
    try {
      success = document.execCommand('copy')
    } catch (e) {
      success = false
    }
    return success
  }
複製代碼

  經過 execCommand 執行 copy 命令,能夠將上述選中的文本添加到系統剪貼板中,接下來用戶只須要在使用的地方按下 Ctrl(command) + V 便可粘貼該內容。

4、特殊狀況的處理

  上述方案基本上能夠應對大部分的狀況,可是在 HTML 中,部分元素中的文本是沒法被選中的,例如:

<select id="js-select">
    <option value="apple">apple</option>
    <option value="banana">banana</option>
    <option value="peach">peach</option>
  </select>
複製代碼

  既然 select 元素中的文本沒法被選中,那麼就沒法調用 execCommand 方法,又何談模擬用戶複製該文本呢?

  這裏就須要採用如下套路:

一、獲取須要複製的文本

  首先獲取到須要複製的文本內容,對於 select 元素,其文本內容能夠根據 value 屬性獲取:

const element = document.getElementById('js-select')
  const text = element.value
複製代碼
二、建立透明元素

  前面提到的 input、textarea 等元素都是能夠被選中的,因此這裏筆者選擇建立一個透明的 textarea 來實現接下來的功能:

function createFakerElement (text) {
    const fakerElement = document.createElement('textarea')
    fakerElement.style.position = 'absolute'
    fakerElement.style.left = '-9999px'
    fakerElement.value = text
    document.body.appendChild(fakerElement)

    return fakerElement
  }
複製代碼
三、選中文本

  前面也提到選中文本有兩種方式:

  • 對於 input、textarea 元素,能夠直接調用其 select 方法。
  • 對於大多數元素(input 和 textarea 元素就是特例之一),能夠經過 Selection 和 Range 完成選中文本的操做。

  因爲上述建立的是 textarea,這裏直接調用 select 方法:

function selectInput (element) {
    return element.select()
  }
複製代碼
四、操做系統剪貼板

  前文已經說起,這裏再也不贅述。

  接下來只要按照順序執行這些操做便可:

document.getElementById('js-button').addEventListener('click', () => {
    const element = document.getElementById('js-select')
    // 一、獲取須要的文本內容
    const text = element.value

    // 二、建立透明的 textarea 元素
    const fakerElement = createFakerElement(text)

    // 三、選中相應的文本
    selectInput(fakerElement)

    // 四、執行操做系統剪貼板的 copy 命令
    const success = copyText()

    if (success) {
      console.log('複製成功')
    } else {
      console.log('複製失敗')
    }

    document.body.removeChild(fakerElement)
  }, false)
複製代碼

5、總結

  由上文可知,前端模擬用戶的複製操做主要涉及兩方面的知識:

  • 利用 Selection 和 Range 對象完成文本選中操做,比較特殊的是 input 和 textarea 元素自帶 select 方法實現該操做。
  • 經過 document.execCommand 方法調用 copy 命令將內容保存到系統剪貼板中。

  其中 document.execCommand 方法主要做用於 Selection 對象,因此當元素沒法被選中時,該複製命令則沒法達到預期的效果。

  前面也到了 disabled 屬性以及 select 元素這樣的特例,相比較下,經過建立一個透明的 textarea 來模擬複製操做的方案可用性更高。

  參考文獻

  相關文章推薦

  寫在最後

  若是本文對您有幫助,點個贊吧!也歡迎小夥伴們關注個人訂閱號 漫談大前端

相關文章
相關標籤/搜索