20 行 JS 代碼實現粘貼板功能

小白沖沖沖沖 發佈 2020-02-10T20:19:37+00:00

作為碼農都應知道,Tab,Ctrl/Cmd+ A,Ctrl / Cmd + C以及Ctrl / Cmd + V分別是自動聚焦、複製、粘貼的快捷鍵。 alert; }


使用剪貼板是一項基本技能。作為碼農都應知道,Tab,Ctrl/Cmd + A,Ctrl / Cmd + C以及Ctrl / Cmd + V分別是自動聚焦、複製、粘貼的快捷鍵。


而對普通用戶可能就不太容易了。即使用戶知道剪貼板是什麼,(除了)那些眼神極好或反應很快的人,其他情況下很難以突出顯示他們想要的確切文字。若用戶不知道鍵盤快捷鍵,也看不到隱藏的編輯菜單,或從未使用右鍵菜單或不知道長按觸屏彈出選項菜單,那麼他很可能無法察覺到複製功能。


那麼我們是否應該提供一個「複製到剪貼板」按鈕來幫助用戶?這功能應該會很有用,即使是對快捷鍵的人非常熟悉的用戶來說。


關於剪貼板的安全


幾年前,瀏覽器不可能直接使用剪貼板。開發人員不得不通過Flash來實現。


剪貼板看起來無關緊要,但想像一下,如果瀏覽器能夠隨意查看和操作內容,會發生什麼。JS腳本(包括第三方腳本)能查看剪貼板內的文本信息,並將密碼,敏感信息甚至整個文檔發送到遠程伺服器。


現在的剪貼板基本功能有限,有如下限制:


  1. 大多數瀏覽器支持剪貼板,除了Safari。(譯註,Safari其實已經支持)
  2. 支持因瀏覽器而異,有些功能不完整或有問題。
  3. 事件必須由用戶必須發起,如點擊滑鼠或按下鍵盤。腳本不能自由訪問剪貼板。


document.execCommand()


此方法就是實現剪貼板的關鍵,它可以傳入cut,copy,paste三種參數。從最常用的document.execCommand('copy')開始介紹。


在使用之前,我們應該檢查瀏覽器是否支持copy命令:document.queryCommandSupported('copy');或document.queryCommandEnabled('copy');,這兩個方法效果相同。


但在Chrome下,儘管Chrome確實支持使用copy命名,但兩個方法都返回false。所以最好是將檢查代碼包在一個try-catch代碼塊中。


下一步,我們應該允許用戶複製什麼呢?必須突出顯示文本,所有瀏覽器都可用select()方法選擇文本input和textarea內的文本。同時Firefox和Chrome / Opera也支持document.createRange方法,該方法允許從任何元素中選擇文本,如下:

<input id="copyme" value="text in this field will be copied" />
<button data-clipboard-target="#copyme">copy</button>

但IE / Edge不支持。

clipboard.js


若你不想自己實現一個較為健壯的跨瀏覽器剪貼板方法的話,clipboard.js可以幫你。它有好幾種設置選項的方式,如H5的data屬性,設置綁定觸發元素以及目標元素,如:

<input id="copyme" value="text in this field will be copied" />
<button data-clipboard-target="#copyme">copy</button>

自己動手實現


clipboard.js大小僅2Kb,若僅實現如下的部分功能的話,那麼可以在20行的代碼內實現:


  1. 僅部分表單元素可被複製
  2. 若在不支持的瀏覽器中(沒錯,就是指Safari)(譯註,Safari其實已經支持),可突出顯示選中文本,並提示用戶按Ctrl / Cmd + C。


像clipboard.js一樣,先創建一個button用於觸發方法,它具有一個data屬性data-copytarget,指向要copy的元素(即#website)

<input type="text" id="website" value="http://www.sitepoint.com/" />
<button data-copytarget="#website">copy</button>

一個立即執行函數表達式綁定click事件的函數,該函數用於解析data-copytarget屬性內容,選擇對應欄位的文本並執行document.execCommand('copy'),。若失敗,文本保持選中狀態,顯示提示框:

(function() {
  'use strict';
  // click events  
  document.body.addEventListener('click', copy, true);
  //event handler  
  function copy(e) {
    //  find target element    
    var      
     t = e.target,      
     c = t.dataset.copytarget,      
     inp = (c ? document.querySelector(c) : null);
    // is element selectable?    
    if (inp && inp.select) {
      // select text      
      inp.select();
      try {        
      // copy text        
      document.execCommand('copy');        
      inp.blur();      }      
      catch (err) {        
      alert('please press Ctrl/Cmd+C to copy');      }
    }  }})();

示例地址:https://codepen.io/SitePoint/pen/vNvEwE/


雖然在上例中,算上樣式和動畫的代碼,代碼已經超過20行了,但動畫和樣式是可選的。


總結:


  1. 通過.select()選擇要複製的表單元素的內容
  2. 調用document.execCommand("copy")方法
  3. 調用.blur()方法,從表單元素中移除焦點
  4. 將第2、3步包在try catch塊中,在不支持的瀏覽器下則提示


其他方式


有很多新穎的剪貼板應用方式。例如Trello.com,將滑鼠懸停在卡片上時,可以按Ctrl / Cmd + C 並將該卡片的連結地址複製到剪貼板。其背後實現的方式為:先創建一個包含URL的隱藏表單元素,然後選中並複製其內容。非常巧妙且實用 —— 我懷疑很少有用戶知道這個功能!

我自己是一名從事了多年開發的web前端老程式設計師,目前辭職在做自己的web前端私人定製課程,去年我花了一個月整理了一份最適合2019年學習的web前端學習乾貨,各種框架都有整理,送給每一位前端小夥伴,想要獲取的可以關注我的頭條號並在後台私信我:前端,即可免費獲取。



原文連結: zcfy.cc/article/roll-your-own-copy-to-clipboard-feature-in-20-lines-of-javascript-sitepoint

關鍵字: