欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript實(shí)現(xiàn)復(fù)制粘貼剪切功能三種方法

 更新時(shí)間:2024年01月28日 15:44:19   作者:持久的棒棒君  
這篇文章主要給大家介紹了關(guān)于JavaScript實(shí)現(xiàn)復(fù)制粘貼剪切功能的相關(guān)資料,在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的開發(fā)需求,文中通過代碼將三種方法介紹的非常詳細(xì),需要的朋友可以參考下

方式一:原生方式實(shí)現(xiàn)復(fù)制粘貼剪切(不推薦)

使用瀏覽器自帶的document.execCommand('copy')實(shí)現(xiàn)復(fù)制,document.execCommand('paste')實(shí)現(xiàn)粘貼,document.execCommand('cut')實(shí)現(xiàn)剪切,這三個(gè)方法的返回值是布爾類型,用來判斷當(dāng)前瀏覽器中能夠使用這些方法,true表示方法能用,false表示方法不能用,目前因?yàn)?code>document.execCommand('paste')涉及到安全問題,考慮到安全原因, document.execCommand(‘paste’)操作已經(jīng)被禁止了。

補(bǔ)充說明下,目前官方已經(jīng)不推薦使用原生方式進(jìn)行復(fù)制粘貼操作了,這幾種方法隨時(shí)可能會(huì)被刪掉

代碼如下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" id="input" value="123" />
    <button onclick="copy1()">復(fù)制(復(fù)制可編輯的標(biāo)簽中的內(nèi)容)</button>
    <button onclick="copy2('這是復(fù)制的內(nèi)容')">復(fù)制(將可編輯的標(biāo)簽隱藏)</button>
    <button onclick="cut()">剪切</button>
    <button onclick="paste()">粘貼</button>
    <input type="text" id="output">
    <script>
        // 復(fù)制可編輯標(biāo)簽中的value值得內(nèi)容
      function copy1() {
        const inputEle = document.querySelector("#input");
        inputEle.select(); // 鼠標(biāo)選擇的內(nèi)容
        document.execCommand("copy"); // 復(fù)制
      }

      /**
       * 如果想使用 execCommand 方法,又不想頁(yè)面中出現(xiàn)可編輯區(qū)域,可以用下述辦法取巧
       * @content 是要復(fù)制的內(nèi)容
      */
      function copy2(content) {
        const dom = document.createElement("input");
        dom.value = content;
        document.body.appendChild(dom);
        dom.select();
        document.execCommand("copy");
        document.body.removeChild(dom);
      }

      // 剪切功能
      function cut(){
        console.log("cut");
        document.execCommand("cut")
      }

      // 粘貼功能:注意,只會(huì)在光標(biāo)所在位置進(jìn)行粘貼
      // function paste(){
      //   const pasteText = document.querySelector("#output")
      //   pasteText.focus() // 讓光標(biāo)聚焦到output標(biāo)識(shí)的輸入框上
      //   document.execCommand("paste"); // 截至目前該方法涉及到安全問題已失效
      // }
    </script>
  </body>
</html>

使用execCommand命令存在以下缺陷:
(1)不夠靈活。只能操作input, textarea或具有contenteditable屬性的元素
(2)execCommand是同步操作,如果復(fù)制/粘貼大量數(shù)據(jù),頁(yè)面會(huì)出現(xiàn)卡頓。
(3)有些瀏覽器還會(huì)跳出提示框,要求用戶許可,這時(shí)在用戶做出選擇前,頁(yè)面會(huì)失去響應(yīng)。
(4)它只能將選中的內(nèi)容復(fù)制到剪貼板,無法向剪貼板任意寫入內(nèi)容

方式二:瀏覽器自帶clipboard API實(shí)現(xiàn)復(fù)制粘貼(推薦)

簡(jiǎn)介

ClipboardAPI是下一代的剪貼板操作方法,比傳統(tǒng)的document.execCommand()方法更加強(qiáng)大、更合理。

特點(diǎn)

(1)它的所有操作都是異步進(jìn)行的,返回promise對(duì)象,不糊造成頁(yè)面卡頓,

(2)它可以將任何內(nèi)容(例如圖片)放入到剪貼板。

(3)安全。通過navigator.clipboard屬性返回Clipboard對(duì)象,所有操作都通過這個(gè)對(duì)象進(jìn)行,如果navigator.clipboard屬性返回undefined,就說明當(dāng)前瀏覽器不支持這個(gè)API

1)有時(shí)候用戶可能會(huì)把敏感數(shù)據(jù)(比如密碼)放在剪貼板允許腳本任意讀取會(huì)產(chǎn)生風(fēng)險(xiǎn),而通過Clipboard對(duì)象進(jìn)行判斷,則很好的避免了這個(gè)風(fēng)險(xiǎn)。

2)此外,有些瀏覽器規(guī)定(例如Chrome),只有HTTPS協(xié)議(或者開發(fā)環(huán)境、本地環(huán)境下)的頁(yè)面才能使用這個(gè)API,由于從 Chrome 76 開始,Clipboard API 將不再被允許在非加密環(huán)境下(即純 HTTP)使用。這是因?yàn)樵?HTTP 環(huán)境下,網(wǎng)絡(luò)傳輸是明文的,容易被竊聽和篡改,因此會(huì)引入安全風(fēng)險(xiǎn)。

3)其次,復(fù)制權(quán)限是用戶默認(rèn)賦予的,而粘貼權(quán)限是需要用戶手動(dòng)同意的,例如,在寫入剪貼板時(shí)腳本可以自動(dòng)完成,但是讀取剪貼板時(shí),瀏覽器會(huì)彈出一個(gè)對(duì)話框咨詢用戶是否同意讀取。

(4)有一點(diǎn)需要特別注意,腳本讀取的是當(dāng)前頁(yè)面的剪切板(注意我說的是瀏覽器中的剪貼板,而不是電腦操作系統(tǒng)自帶的剪貼板),這帶來一個(gè)問題,如果想把相關(guān)的代碼粘貼到開發(fā)者工具中直接運(yùn)行,可能會(huì)報(bào)錯(cuò),因?yàn)檫@時(shí)的當(dāng)前頁(yè)面是開發(fā)者工具的窗口,而不是網(wǎng)頁(yè)頁(yè)面。
例如:你把下面的代碼粘貼到開發(fā)者工具運(yùn)行就會(huì)報(bào)錯(cuò)。

(async () => {
  const text = await navigator.clipboard.readText();
  console.log(text);
})();

因?yàn)樵诖a運(yùn)行的時(shí)候,開發(fā)者工具窗口是當(dāng)前頁(yè),這個(gè)頁(yè)面不存在ClipboardAPI依賴的DOM接口。

解決辦法是將相關(guān)代碼放到setTimeout()里面延遲運(yùn)行,在調(diào)用函數(shù)之前快速點(diǎn)擊瀏覽器的頁(yè)面窗口,將其變成當(dāng)前頁(yè)。

setTimeout(async () => {
  const text = await navigator.clipboard.readText();
  console.log(text);
}, 2000);

clipboard對(duì)象及相關(guān)API

clipboard對(duì)象提供了四個(gè)方法用來讀寫剪貼板,他們都是異步方法,返回promise對(duì)象。

Clipboard.readText()

Clipboard.readText()方法用來復(fù)制剪貼板也就是粘貼功能)里面的文本數(shù)據(jù)。

該方法返回的是Promise對(duì)象,那么我這里提供兩種使用形式

  • 形式一:pormise回調(diào)實(shí)現(xiàn)
// 普通方法
function paste() {
  navigator.clipboard // 創(chuàng)建clipboard對(duì)象
    .readText() // 調(diào)用readText()方法
    .then((clipText) => {
      // 成功回調(diào) 
      console.log(clipText); // clipText是從剪貼板讀取到的內(nèi)容(也就是要粘貼的內(nèi)容)
    })
    .catch((err) => console.log("粘貼失??!",err)); // 失敗回調(diào)
}
  • 形式二:async函數(shù)
// async 函數(shù)
async function paste(){
  try{
    // 創(chuàng)建clipboard對(duì)象并調(diào)用readText()方法讀取剪貼板上的內(nèi)容進(jìn)行返回
    const text = await navigator.clipboard.readText() 
    console.log("要粘貼的內(nèi)容為:",text); // 具體粘貼到哪你自己決定
  }catch(err){
    // catch捕獲處理報(bào)錯(cuò)
    console.log("粘貼失敗!",err);
  }
}

注意,如果用戶不允許使用這個(gè)API進(jìn)行粘貼操作,那么腳本就會(huì)報(bào)錯(cuò),那么我們就可以用catch()方法進(jìn)行處理報(bào)錯(cuò)。

Clipboard.read()

Clipboard.read()方法用于復(fù)制剪貼板也就是粘貼功能)里面的數(shù)據(jù),可以是文本數(shù)據(jù),也可以是二進(jìn)制數(shù)據(jù)(比如圖片)。該方法需要用戶明確給予許可。

該方法返回一個(gè) Promise 對(duì)象。一旦該對(duì)象的狀態(tài)變?yōu)?resolved,就可以獲得一個(gè)數(shù)組,每個(gè)數(shù)組成員都是 ClipboardItem 對(duì)象的實(shí)例。

下面我們簡(jiǎn)單介紹下代碼中用到的幾個(gè)對(duì)象屬性和方法

遍歷通過Clipboard.read()方法成功回調(diào)得到的數(shù)組對(duì)象,由此得到一個(gè)個(gè)的ClipboardItem 對(duì)象,表示一個(gè)單獨(dú)的剪貼項(xiàng),每個(gè)剪貼項(xiàng)都擁有ClipboardItem.types屬性ClipboardItem.getType()方法

1、ClipboardItem.types屬性返回一個(gè)數(shù)組,里面的成員是該剪貼項(xiàng)可用的 MIME 類型,比如某個(gè)剪貼項(xiàng)可以用 HTML 格式粘貼,也可以用純文本格式粘貼,那么它就有兩個(gè) MIME 類型(text/html和text/plain)。

2、ClipboardItem.getType(type)方法用于讀取剪貼項(xiàng)的數(shù)據(jù),返回一個(gè) Promise 對(duì)象。該方法接受剪貼項(xiàng)的 MIME 類型作為參數(shù),返回該類型的數(shù)據(jù),該參數(shù)是必需的,否則會(huì)報(bào)錯(cuò)。

代碼示例如下

  • 形式一:promise回調(diào)實(shí)現(xiàn)
// 粘貼任何類型的數(shù)據(jù)
function paste() {
  navigator.clipboard
    .read() // 調(diào)用read()方法從剪貼板讀取數(shù)據(jù)進(jìn)行粘貼操作
    .then((clipboardItems) => {
      console.log(clipboardItems,"clipboardItems =========");
      // clipboardItems是一個(gè)數(shù)組
      for (const clipboardItem of clipboardItems) {
        console.log(clipboardItem, "clipboardItem ========="); // clipboardItem是一個(gè)實(shí)例對(duì)象
        for (const type of clipboardItem.types) { // clipboardItem.types返回一個(gè)數(shù)組,存儲(chǔ)的是每一段剪貼板的mine數(shù)據(jù)類型
          clipboardItem
            .getType(type) // 讀取接收到的mine類型作為參數(shù),返回該類型的數(shù)據(jù)
            .then((res) => console.log(res))
            .catch((err) => console.log(err));
        }
      }
    })
    .catch((err) => {
      console.log(err.name,err.message)
    });
}
  • 形式二:async函數(shù)+await實(shí)現(xiàn)
async function paste(){
 try {
  const clipboardItems = await navigator.clipboard.read()
  for(const clipboardItem of clipboardItems){
    for(const type of clipboardItem.types){
      const result = await clipboardItem.getType(type)
      console.log(result);
    }
  }
 } catch (err) {
  console.log(err.name,err.message);
 }
}

顯然使用第二種方式實(shí)現(xiàn)代碼更簡(jiǎn)單。

Clipboard.writeText()

Clipboard.writeText()方法用于將文本內(nèi)容寫入剪貼板(也就是復(fù)制功能),該方法同樣返回一個(gè)Promise對(duì)象。
代碼示例如下:
下面代碼功能是:通過點(diǎn)擊頁(yè)面,將數(shù)據(jù)復(fù)制到剪貼板。

document.body.addEventListener('click',async (e) => {
    await navigator.clipboard.writeText('Yo') // 參數(shù)是要寫入的文本
  }
)

當(dāng)然你可以通過點(diǎn)擊一個(gè)按鈕,一個(gè)標(biāo)簽等來觸發(fā)該復(fù)制操作。

Clipboard.write()

Clipboard.write()方法用于將任意數(shù)據(jù)寫入剪貼板,可以是文本數(shù)據(jù),也可以是二進(jìn)制數(shù)據(jù)。

該方法接受一個(gè) ClipboardItem 實(shí)例作為參數(shù),表示寫入剪貼板的數(shù)據(jù)。

  • 代碼示例復(fù)制一個(gè)圖片類型
async function copy1() {
  try {
  	// 圖片地址
    const imgURL = "https://dummyimage.com/300.png"; 
    // 獲取圖片
    const data = await fetch(imgURL); 
    // 將圖片轉(zhuǎn)為blob類型
    const blob = await data.blob(); 
    // 將數(shù)據(jù)寫入(復(fù)制)到剪貼板
    await navigator.clipboard.write([ 
      // 創(chuàng)建Clipboard實(shí)例對(duì)象,對(duì)象的鍵名是數(shù)據(jù)的 MIME 類型,鍵值就是數(shù)據(jù)本身
      new ClipboardItem({ 
        [blob.type]: blob,
      }),
    ]);
    console.log("Image copied.");
  } catch (err) {
    console.error(err.name, err.message);
  }
}

ClipboardItem()瀏覽器原生提供的構(gòu)造函數(shù),用來生成ClipboardItem實(shí)例,它接收一個(gè)對(duì)象作為參數(shù),該對(duì)象的鍵名是數(shù)據(jù)的 MIME 類型,鍵值就是數(shù)據(jù)本身。

注意,Chrome 瀏覽器目前只支持寫入 PNG 格式的圖片。

此外,write()方法還可以將用一個(gè)剪貼項(xiàng)的多種格式的值寫入到剪貼板,一種是文本數(shù)據(jù),一種是二進(jìn)制數(shù)據(jù),供不同的場(chǎng)合粘貼使用。

function copy() {
  const image = await fetch('kitten.png'); // 獲取圖片類型的數(shù)據(jù)
  const blob = await image.blob(); // 將圖片轉(zhuǎn)為blob對(duì)象
  const text = new Blob(['Cute sleeping kitten'], {type: 'text/plain'}); // 獲取文字類型的數(shù)據(jù)并轉(zhuǎn)為blob實(shí)例對(duì)象
  const item = new ClipboardItem({
    'text/plain': text,
    [blob.type]: image
  });
  await navigator.clipboard.write([item]);
}

就是剪貼板中的剪貼項(xiàng)有兩種類型的數(shù)據(jù),在你要圖片時(shí),我就將剪貼板中的數(shù)據(jù)用圖片的形式給你粘貼使用,要用文字時(shí),就粘貼文字給你。

方式三:clipboard.js插件庫(kù)實(shí)現(xiàn)復(fù)制剪切(推薦)

它是一個(gè)不需要Flash,就能實(shí)現(xiàn)文本復(fù)制或者剪切到剪切板的輕量級(jí)插件(注意沒有粘貼哦)

官網(wǎng):clipboard.js

安裝引入

# node安裝
npm install clipboard --save
<!-- html文件中可以使用CDN引入 -->
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js"></script>

// js文件中可以通過ES6語(yǔ)法的import或者commonjs進(jìn)行引入或者使用其他引入方式

這個(gè)庫(kù)同時(shí)依賴于SelectionexecCommand api。所有瀏覽器都支持第一個(gè),而以下瀏覽器支持第二個(gè)。chrome42+,Edge12+,F(xiàn)irefox41+,IE9+,Opera2+,Safari0+

基本使用

總共有兩步,第一步在指定的html標(biāo)簽中使用指定屬性進(jìn)行綁定,第二部創(chuàng)建Clipboard實(shí)例對(duì)象調(diào)用相關(guān)的event事件,操作如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- 引入clipboard.js -->
    <script src="https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.11/clipboard.js"></script>
    <title>Document</title>
  </head>
  <body>
    <div>
      <!-- Target -->
      <input type="text" id="foo" value="要復(fù)制的內(nèi)容" />

      <!-- Trigger -->
      <button class="btn" data-clipboard-target="#foo" data-clipboard-action="copy">復(fù)制</button>
      <!-- 
        有兩個(gè)屬性值:
        data-clipboard-target:取值是一個(gè)選擇器對(duì)象,用來綁定要復(fù)制的標(biāo)簽,復(fù)制其內(nèi)容
        data-clipboard-action:用來決定是復(fù)制還是粘貼,有兩個(gè)取值:copy和cut
       -->
    </div>
    <script>
        // 創(chuàng)建一個(gè)實(shí)例對(duì)象,參數(shù)是一個(gè)選擇器,綁定的是觸發(fā)復(fù)制/剪切事件的標(biāo)簽
      var clipboard = new ClipboardJS(".btn");

      // 成功回調(diào)
      clipboard.on("success", function (e) {
        console.info("Action:", e.action); // 操作:copy或者cut
        console.info("Text:", e.text); // 復(fù)制/剪切的內(nèi)容
        console.info("Trigger:", e.trigger); // 觸發(fā)對(duì)象

        e.clearSelection();
      });

      // 失敗回調(diào)
      clipboard.on("error", function (e) {
        console.error("Action:", e.action); // 操作:copy或者cut
        console.error("Trigger:", e.trigger); // 觸發(fā)對(duì)象
      });
    </script>
  </body>
</html>

可以通過ClipboardJS.isSupported()方法判斷瀏覽器是否可以使用這個(gè)庫(kù)

進(jìn)階使用

new ClipboardJS("選擇器",{...})方法,第二個(gè)參數(shù)是一個(gè)對(duì)象,你可以往里面?zhèn)魅牖卣{(diào)函數(shù),如下

(1)通過函數(shù)返回要綁定的節(jié)點(diǎn)target

new ClipboardJS('.btn', {
    target: function(trigger) {
        return trigger.nextElementSibling;
    }
});

(2)通過函數(shù)設(shè)置要復(fù)制的文本內(nèi)容text

new ClipboardJS('.btn', {
    text: function(trigger) {
        return trigger.getAttribute('aria-label');
    }
});

(3)在Bootstrap Modals 中或與任何其他更改焦點(diǎn)的庫(kù)一起使用時(shí),將焦點(diǎn)元素設(shè)置為 container 值

new ClipboardJS('.btn', {
    container: document.getElementById('modal')
});

(4)銷毀復(fù)制粘貼的實(shí)例對(duì)象(如果在單頁(yè)應(yīng)用中使用時(shí),要更精確地管理DOM的生命周期,可以使用以下方法清除創(chuàng)建的事件對(duì)象)

var clipboard = new ClipboardJS('.btn');
clipboard.destroy();

可以看到這個(gè)插件庫(kù)基本的功能是復(fù)制和剪切,沒有涉及到粘貼操作,所以,通常會(huì)和瀏覽器自帶clipboardAPI配合使用實(shí)現(xiàn)復(fù)制粘貼操作。

補(bǔ)充:復(fù)制粘貼操作攔截

主要用到了copy和paste事件

copy

例如:復(fù)制操作時(shí),將用戶放入到剪貼板中的文本轉(zhuǎn)為大寫

const source = document.querySelector('.source');

source.addEventListener('copy', (event) => {
  const selection = document.getSelection();
  event.clipboardData.setData('text/plain', selection.toString().toUpperCase());
  event.preventDefault();
});

上面示例中,事件對(duì)象的clipboardData屬性包含了剪貼板數(shù)據(jù)。它是一個(gè)對(duì)象,有以下屬性和方法。
Event.clipboardData.setData(type, data):修改剪貼板數(shù)據(jù),需要指定數(shù)據(jù)類型。
Event.clipboardData.getData(type):獲取剪貼板數(shù)據(jù),需要指定數(shù)據(jù)類型
Event.clipboardData.clearData([type]):清除剪貼板數(shù)據(jù),可以指定數(shù)據(jù)類型。如果不指定類型,將清除所有類型的數(shù)據(jù)。
Event.clipboardData.items:一個(gè)類似數(shù)組的對(duì)象,包含了所有剪貼項(xiàng),不過通常只有一個(gè)剪貼項(xiàng)。

例如:攔截用戶的復(fù)制操作,將指定內(nèi)容放入剪貼板

onst clipboardItems = [];

document.addEventListener('copy', async (e) => {
  e.preventDefault(); // 先使用該方法組織默認(rèn)事件,然后由腳本接管復(fù)制操作
  try {
    let clipboardItems = [];
    for (const item of e.clipboardData.items) {
      if (!item.type.startsWith('image/')) {
        continue;
      }
      clipboardItems.push(
        new ClipboardItem({
          [item.type]: item,
        })
      );
      await navigator.clipboard.write(clipboardItems);
      console.log('Image copied.');
    }
  } catch (err) {
    console.error(err.name, err.message);
  }
});

paste

用戶使用剪貼板數(shù)據(jù),進(jìn)行粘貼操作時(shí),會(huì)觸發(fā)paste事件

document.addEventListener('paste', async (e) => {
  e.preventDefault();
  const text = await navigator.clipboard.readText();
  console.log('Pasted text: ', text);
});

總結(jié) 

到此這篇關(guān)于JavaScript實(shí)現(xiàn)復(fù)制粘貼剪切功能的文章就介紹到這了,更多相關(guān)JS復(fù)制粘貼剪切功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論