首頁  >  文章  >  web前端  >  一起看看JavaScript非同步剪貼簿API

一起看看JavaScript非同步剪貼簿API

coldplay.xixi
coldplay.xixi轉載
2020-06-17 16:00:322277瀏覽

一起看看JavaScript非同步剪貼簿API

在過去的幾年裡我們只能使用 document.execCommand 來操作剪貼簿。不過,這種操作剪貼簿的操作是同步的,而且只能讀取和寫入 DOM。

現在 Chrome 66 已經支援了新的 Async Clipboard API,作為 execCommand 替代品。

這個新的 Async Clipboard API 也可以使用 Promise 來簡化剪貼簿事件並將它們與 Drag-&-Drop API 一起使用。

複製:將文字寫入剪貼簿

writeText() 可以把文字寫入剪貼簿。 writeText() 是非同步的,它回傳一個Promise:

navigator.clipboard.writeText('要复制的文本')
  .then(() => {
    console.log('文本已经成功复制到剪切板');
  })
  .catch(err => {
    // This can happen if the user denies clipboard permissions:
    // 如果用户没有授权,则抛出异常
    console.error('无法复制此文本:', err);
  });

也可以使用非同步函數的asyncawait

async function copyPageUrl() {
  try {
    await navigator.clipboard.writeText(location.href);
    console.log('Page URL copied to clipboard');
  } catch (err) {
    console.error('Failed to copy: ', err);
  }
}

貼上:從剪貼簿中讀取文字

和複製一樣,可以透過呼叫readText() 從剪貼簿中讀取文本,該函數也傳回一個Promise:

navigator.clipboard.readText()
  .then(text => {
    console.log('Pasted content: ', text);
  })
  .catch(err => {
    console.error('Failed to read clipboard contents: ', err);
  });

為了保持一致性,以下是等效的非同步函數:

async function getClipboardContents() {
  try {
    const text = await navigator.clipboard.readText();
    console.log('Pasted content: ', text);
  } catch (err) {
    console.error('Failed to read clipboard contents: ', err);
  }
}

處理貼上事件

有計畫推出偵測剪貼簿變更的新事件,但現在最好使用“貼上”事件。它很適合用於閱讀剪貼簿文字的新非同步方法:

document.addEventListener('paste', event => {
  event.preventDefault();
  navigator.clipboard.readText().then(text => {
    console.log('Pasted text: ', text);
  });
});

安全和權限

#剪貼簿存取一直為瀏覽器帶來安全問題。如果沒有適當的權限,頁面可能會悄悄地將所有惡意內容複製到使用者的剪貼簿,貼上時會產生災難性的結果。想像一下,一個網頁,靜靜地複製 rm -rf / 或解壓縮炸彈圖像到剪貼簿。

讓網頁不受限制地讀取剪貼簿會更加麻煩。使用者經常將敏感資訊(如密碼和個人詳細資料)複製到剪貼簿,然後可以透過任何頁面閱讀,而使用者根本無法察覺。

與許多新的 API 一樣,navigator.clipboard 僅支援透過 HTTPS 提供的頁面。為了防止濫用,只有當頁面處於活動標籤時才允許剪貼簿存取。活動標籤中的頁面可以在不要求權限的情況下寫入剪貼板,但從剪貼簿中讀取始終需要權限。

為了更容易,複製和貼上的兩個新權限已新增到 Permissions API 中。當頁面處於活動標籤時,clipboard-write 權限會自動授予頁面。當您透過從剪貼簿讀取資料時,則必須要求取得 clipboard-read 權限。

{ name: 'clipboard-read' }
{ name: 'clipboard-write' }

图0:JavaScript异步剪贴板 API

與使用權限API 的任何其它內容一樣,可以檢查您的應用程式是否具有與剪貼簿互動的權限:

navigator.permissions.query({
  name: 'clipboard-read'
}).then(permissionStatus => {
  // permissionStatus.state 的值是 'granted'、'denied'、'prompt':
  console.log(permissionStatus.state);

  // 监听权限状态改变事件
  permissionStatus.onchange = () => {
    console.log(permissionStatus.state);
  };
});

以下是剪貼板API 的「非同步」部分真正派上用場的地方:嘗試讀取或寫入剪貼簿資料將自動提示使用者獲得權限(如果尚未授予)。由於 API 是基於 Promise 的,因此如果使用者拒絕剪貼簿權限時,Promise 將被 reject,因此頁面可以適當地回應。

因為只有當頁面是當前活動選項卡時,Chrome 才允許剪貼簿訪問,因此如果直接粘貼到DevTools 中,則會發現這裡的一些示例運行不正確,因為此時DevTools 本身是活動選項卡(頁面不是活動選項卡)。有一個技巧:我們需要使用setTimeout 推遲剪貼簿訪問,然後在調用函數之前快速單擊頁面內部以使頁面獲取焦點:

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

回顧

#在引入異步剪貼簿API 之前,我們在Web 瀏覽器中混合了不同的複製和貼上實作。

在大多數瀏覽器中,可以使用document.execCommand('copy') 和觸發瀏覽器自己的複製和貼上document.execCommand('paste')。如果要複製的文字是不存在於DOM 中的字串,我們必須將其插入到DOM 中並選擇它:

button.addEventListener('click', e => {
  const input = document.createElement('input');
  document.body.appendChild(input);
  input.value = text;
  input.focus();
  input.select();
  const result = document.execCommand('copy');
  if (result === 'unsuccessful') {
    console.error('Failed to copy text.');
  }
})

同樣,以下是您如何在不支援新的Async Clipboard API 的瀏覽器中處理貼上的內容:

出自:https://github.com/justjavac/the-front-end-knowledge-you-may-not-know/issues/23

document.addEventListener('paste', e => {
  const text = e.clipboardData.getData('text/plain');
  console.log('Got pasted text: ', text);
})

在Internet Explorer 中,我們也可以透過window.clipboardData 存取剪貼簿。如果在使用者手勢內進行存取(例如點擊事件) – 以負責任的方式請求權限的一部分 – 則不顯示權限提示。

偵測和回退

在支援所有瀏覽器的同時,使用功能偵測來利用非同步剪貼簿是個不錯的主意。您可以透過檢查 navigator.clipboard 來偵測對 Async Clipboard API 的支援:

document.addEventListener('paste', async e => {
  let text;
  if (navigator.clipboard) {
    text = await navigator.clipboard.readText()
  }
  else {
    text = e.clipboardData.getData('text/plain');
  }
  console.log('Got pasted text: ', text);
});

异步剪贴板 API 的下一步是什么?

正如你可能已经注意到的那样,这篇文章只涵盖了 navigator.clipboard 的文本部分。规范中有更多的通用 read()write() 方法,但是这些会带来额外的实现复杂性和安全性问题(请记住那些图像炸弹?)。目前,Chrome 正在推出更简单的 API 文本部分。

出自:justjavac

推荐教程:《javascript基础教程

以上是一起看看JavaScript非同步剪貼簿API的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:webhek.com。如有侵權,請聯絡admin@php.cn刪除