Async Clipboard API 的 SVG 支援

Async Clipboard API 的 Clipboard 介面可提供系統剪貼簿內容的讀取和寫入權限。這可讓網頁應用程式實作剪下、複製和貼上功能。您可以呼叫 read() 方法,將剪貼簿中的資料貼到應用程式中,並呼叫 write() 方法,將資料複製到剪貼簿。除了文字、Portable Network Graphics (PNG) 格式的圖片、經過消毒的未經消毒的 HTML網頁自訂格式之外,Async Clipboard API 現在也支援複製及貼上 SVG 圖片,這表示您終於可以與圖片編輯軟體互動,以更自然的方式處理 SVG,方法是將 SVG 圖片複製及貼上為圖片,而不是文字,或使用不實用的方法

功能偵測 SVG 支援

透過呼叫靜態 ClipboardItem.supports() 方法,並傳遞所需的 MIME 類型,即可偵測是否支援 SVG 圖片 (以及任何其他 MIME 類型)。

const supportsSVG = () => {
  if (
    !('supports' in window.ClipboardItem) ||
    !window.ClipboardItem.supports('image/svg+xml')
  ) {
    return false;
  }
  return true;
};

複製可擴充向量圖形圖片

將物件填入 ClipboardItem,即可複製 SVG 圖片。包含 SVG 圖片資料的 Blob 是值,而 Blob 的類型 (在本例中為 'image/svg+xml') 則是鍵。

copyButton.addEventListener('click', async () => {
  if (!supportsSVG()) {
    return;
  }
  try {
    const blob = await fetch(img.src).then((response) => response.blob());
    await navigator.clipboard.write([
      new window.ClipboardItem({
        [blob.type]: blob,
      }),
    ]);
  } catch (err) {
    console.error(err.name, err.message);
    alert(err.message);
  }
});

貼上可擴充向量圖形圖片

如要貼上 SVG 圖片,請從剪貼簿讀取 ClipboardItem,並使用 getType() 方法取得所需類型 (在本例中為 'image/svg+xml')。這會傳回 blob,一旦轉換為 blob 網址,您就可以將其指派給 <img>src 屬性。

pasteButton.addEventListener('click', async () => {
  if (!supportsSVG()) {
    return;
  }
  const [clipboardItem] = await navigator.clipboard.read();
  const svgBlob = await clipboardItem.getType('image/svg+xml');
  if (!svgBlob) {
    alert('No SVG in the clipboard.');
    return;
  }
  const image = document.createElement('img');
  const blobURL = URL.createObjectURL(svgBlob);
  image.addEventListener('load', () => {
    URL.revokeObjectURL(blobURL);
  });
  image.src = blobURL;
});

清除

SVG 是強大的格式,例如可嵌入指令碼。當使用者貼上來源不明的內容時,這可能會造成危險,因此瀏覽器會執行清理步驟。複製資料時,Async Clipboard API 會產生格式正確的 SVG 文件,然後將其寫入剪貼簿。貼上資料時,片段剖析器會產生經過嚴格處理的 SVG 片段。因此,在貼上操作之前,onclick 事件處理常式屬性仍會存在,但在貼上後就會移除。

macOS 上的 Clipboard Viewer 應用程式,正在檢查剪貼簿內容。這表示 SVG 中的 onclick 事件監聽器屬性仍在。
macOS 上的 Clipboard Viewer 應用程式,檢查剪貼簿內容。這表示 SVG 中的 onclick 事件監聽器屬性仍在。

示範

請參閱 Glitch 的示範,瞭解如何複製及貼上 SVG。請查看原始碼,瞭解運作方式。請務必在複製和貼上前後,嘗試點選任一圓圈。貼上後,系統會移除可能有危險性的 onclick 事件處理常式屬性。

特別銘謝

Microsoft Edge 團隊實作了 Chromium 中 Async 剪貼簿 API 的 SVG 支援功能。本篇文章由 Rachel Andrew 和 Anupam Snigdha 審查。