Kouzelný trik schránky – jak používat různé typy MIME s rozhraním API schránky

Dnes jsem objevil kouzelný trik pro vývoj webu od Cyruse Roshana. Trvalo mi dobrých 20 minut, než jsem přišel na to, jak trik funguje, a naučil jsem se pár věcí o práci se schránkou JavaScriptu a typech MIME. Zní to zajímavě? Čtěte dál!

Vyzkoušejte kouzelnické triky sami; Počkám. 😉

Pokud jste to nezkusili, zde je postup:

  1. Máte za úkol kliknout na herní kartu ASCII art. Znaky karty se automaticky zkopírují do vaší schránky pomocí JavaScriptu.
  2. Poté se na nové obrazovce zobrazí výzva, abyste vložili zkopírovanou kartu ASCII do textové oblasti (což funguje podle očekávání).
  3. Dále budete vyzváni, abyste otevřeli nový dokument Google a vložili do něj obsah schránky (karta ASCII umění).
  4. Právě zkopírovaná grafika ASCII nyní obsahuje nový řádek, který vám říká, že máte vložit stejný obsah do adresního řádku, a bum! 🪄 Právě jste vložili adresu URL profilu Cyrus na Twitteru.

Kdo? To je kouzlo! 🤯

Clipboard API

Poté, co jsem vytvořil patnáct různých dokumentů Google a přemýšlel, zda Cyros nějak vkládá JavaScript do Dokumentů Google (což nedělá), jsem přišel na to, jak tento trik funguje.

Stránka Cyros využívá šikovnou funkci rozhraní JavaScript Clipboard API (navigator.clipboard ), a jako každý kouzelnický trik, jakmile víte, jak to funguje, je to hloupě jednoduché.

Pokud se vývojem webu zabýváte dostatečně dlouho, možná si pamatujete document.execCommand('copy') příkaz. Tento starý způsob interakce se schránkou je nyní zastaralý a nahrazen rozhraním API schránky. Novější API má jediný účel interakce se schránkou a funguje asynchronně. Hurá!

Funguje ale Clipboard API dnes všude? Na první pohled navigator.clipboard Zdá se, že podporuje různé prohlížeče...

MDN Compat Data (zdroj)
Informace o podpoře prohlížeče pro schránku
66 66 79 63 63 13.1 13.1 9.0 66

...ale pozor! Když se na to podíváte hlouběji, zjistíte, že právě proto, že navigator.clipboard je k dispozici, neznamená to, že jsou k dispozici všechny funkce.

Jak umístit prostý text do schránky

Vkládání textu do schránky je jednoduché pomocí API. Zde je příklad.

await navigator.clipboard.writeText(
  "That's some cool copied text, isn't it?"
);

Klikněte na tlačítko níže a vložte nový obsah schránky do vstupních polí, abyste potvrdili, že funguje.

Hřiště

writeText pokrývá mnoho standardních případů použití, ale není to to, co kouzelnický trik používá. Pojďme se ponořit hlouběji!

Jak zapsat různé typy MIME do schránky

Jak je vidět, umístění textu do schránky je rychle hotové. Ale jak byste zacházeli s obrázky nebo jinými textovými formáty, jako je richtext nebo HTML? Je možné je vložit do schránky také pomocí JavaScriptu?

Existuje další způsob, jak vložit obsah do schránky – clipboard.write .

await navigator.clipboard.write([
  new ClipboardItem({
    'text/plain': new Blob(["That's some cool plain text, isn't it?"], {
      type: 'text/plain',
    }),
  }),
]);

clipboard.write nepřijímá řetězce, ale ClipboardItems . Hlavní rozdíl mezi těmito dvěma metodami je v tom, že pokud chcete do schránky vložit cokoliv jiného než prostý text, musíte definovat odpovídající typ MIME pomocí ClipboardItem .

Je to více kódu na psaní, ale podle mého názoru je to stále slušná zkušenost. Milé!

Bohužel ani navigator.clipboard.write ani globální ClipboardItem vlastnost je definována ve Firefoxu v době psaní (oba jsou za dom.events.asyncClipboard.clipboardItem vlajka).

MDN Compat Data (zdroj)
Informace o podpoře prohlížeče pro položku ClipboardItem
66 66 79 87* 87 13.1 13.1 9.0 66

* Další podrobnosti naleznete v MDN.

Neprováděl jsem průzkum, ale pokud hledáte řešení pro různé prohlížeče, jak umístit do schránky jiné věci než text, jsem si jistý, že některé knihovny vás pokryly.

A tady je další příklad na hraní. Vypadá stejně jako předchozí, ale nyní používá navigator.clipboard.write .

Naplňte si schránku!

Hřiště

Už si umíte představit, jak funguje kouzelný trik, když jste viděli nějaký kód?

To je správně; trik je založen na různých typech MIME obsahu. Vstupní pole a textové oblasti zvládnou vložený prostý text v pohodě, ale samozřejmě existují i ​​další dostupné typy MIME.

Schránka může obsahovat typy image/gif , image/jpeg , text/rtf , starý dobrý text/html a všechny druhy fantazie.

A díky Clipboard API máte pod kontrolou typ MIME a můžete dokonce ukládat text a obrázky ve stejné operaci zápisu.

A není to jen jediná operace; je to dokonce jeden záznam ve schránce .

navigator.clipboard.write([
  new ClipboardItem({
    'text/plain': new Blob(["That's some cool plain text, isn't it?"], {
      type: 'text/plain',
    }),
    'text/html': new Blob(
      [
        '<div style="/* some styles */">Oh yeah - text/html!</div>',
      ],
      {
        type: 'text/html',
      }
    ),
  }),
]);

Výše uvedený příklad ukazuje, jak do schránky vložit různý obsah jako prostý text a HTML. 😲

Nyní jde pouze o to, kam obsah vložíte, abyste viděli toto kouzlo v akci.

A div s contentEditable atribut může přijmout a vykreslit HTML. 😲 Pokud vložíte obsah s MIME typem text/html do něj, vykreslí to v pohodě.

Chcete-li to dokázat, stiskněte tlačítko níže a podívejte se, co se stane, když jej vložíte do vstupních polí a upravitelného div .

Hřiště A div s contentEditable

Cyrusův trik využívá tuto funkci.

Zpočátku kouzelný trik vloží do schránky prostý text, ale později uloží ClipboardItem s více typy MIME. text/plain má jeho adresu URL profilu na Twitteru a text/html obsahuje uměleckou kartu ASCII. Dokumenty Google poté vykreslí vložený kód HTML, zatímco panel adresy URL vykreslí prostý text.

Pokud používáte jiné typy MIME než text, je dobré uvést text/plain záložní, pokud váš cíl nerozumí konkrétnímu typu MIME.

Jak zkontrolovat schránku

Zatímco jsem ladil magický trik, zjistil jsem, že kontrola vaší schránky není na MacOS přímočará. I když Finder poskytuje způsob, jak se podívat na to, co je ve schránce (Finder > Edit > Show clipboard ), vždy se zobrazí položka ve formátu prostého textu.

Vytvořil jsem rychlý inspektor schránky pomocí rozhraní Clipboard API read metody. A tady to začalo být velmi zajímavé.

Bohužel je to stejný příběh, kdy Firefox nepodporuje složité interakce se schránkou (je za jiným příznakem – dom.events.asyncClipboard.read ) a přestože Safari podporuje navigator.clipboard.write má pro nás překvapení.

MDN Compat Data (zdroj)
Informace o podpoře prohlížeče pro clipboard.read
86 86 79 90* Ne 13.1 13.1 12.0 84

* Další podrobnosti naleznete v MDN.

MDN vysvětluje použití navigator.read takto:

try {
  const permission = await navigator.permissions.query({ name: 'clipboard-read' });
  if (permission.state === 'denied') {
    throw new Error('Not allowed to read clipboard.');
  }
  const clipboardContents = await navigator.clipboard.read();
  for (const item of clipboardContents) {
    // do things with the clipboard entries
  }
} catch (error) {
  console.error(error.message);
}

V Chromiums to funguje dobře, ale ukázalo se, že Safari nepodporuje navigator.permissions . 🤦‍♂️

MDN Compat Data (zdroj)
Informace o podpoře prohlížeče pro oprávnění
43 43 79 46 46 16 16 4.0 Není

To znamená, že musíte zkontrolovat, zda navigator.permissions je k dispozici také. A pokud ano, požádejte o oprávnění, a pokud ne, zkuste použít navigator.clipboard.read každopádně.

V tomto případě Safari zobrazí malé dialogové okno s oprávněním „Vložit“. Pokud na něj nekliknete, navigator.clipboard.read vyvolá výjimku. Ufff...

Zde je shrnutí, jak používat navigator.clipboard.read :

  • Pro prohlížeče Chromium byste měli používat rozhraní Permissions API.
  • Pomocí Firefoxu nemůžete číst obsah schránky.
  • V Safari to prostě musíte vyzkoušet a zjistit, jestli to funguje.

Bavte se s tím níže.

Hřiště

Poznámka:ne veškerý obsah schránky je přístupný

Zdá se, že kontrola a přístup k textovému obsahu schránky v prohlížeči Chromium funguje dobře. Ale pokud zkopíruji obrázek z MacOS Finder navigator.clipboard.read to se mu také nelíbí a vyhodí No valid data on clipboard výjimka.

Pokud tedy plánujete použít navigator.clipboard.read , musíte funkce detekovat Permissions API a také se ujistit, že try/catch všechny vaše read hovory.

Závěr

Tento malý kouzelnický trik se stal pořádným výletem. Ale tady je to, co jsem se naučil:

  1. Rozhraní API schránky umožňuje do schránky zapisovat více položek v různých typech MIME.
  2. Používání rozhraní Clipboard API je stále obtížné, pokud cílíte na všechny hlavní prohlížeče.
  3. Ne vše ve vaší schránce je dostupné prostřednictvím JavaScriptu.

Pokud se chcete dozvědět více, existuje dobrý článek o asynchronním rozhraní API schránky na web.dev a Thomas vás také pokryl.

A s tímto šťastným lepením! 👋