O webu
Kopírování do schránky

Občas se hodní návštěvníkovi usnadnit/ovlivnit kopírování obsahu do schránky. Jaké existují možnosti?

Zpříjemnění kopírování

Jelikož všechny prohlížeče nenabízejí nějakou standardní metodu, jak požadovaný text přímo zkopírovat do schránky, můžeme uživateli obsah ke zkopírování připravit, aby se mu co nejpohodlněji zkopíroval standardním způsobem klávesovou zkratkou (například) Ctrl + C (nemusel nic složitě v textu označovat a podobně).

Obsah v elementu <input>/<textarea>

U těchto formulářových polí jde využít toho, že se dají snadno celá označit JavaScriptem při kliknutí.

Okno prompt

Další možnost je využít vyskakovacího okna, které běžně slouží (či spíš v minulosti sloužilo) k zadání vstupu od uživatele. S tím, že do pole pro vstup umístíme obsah ke zkopírování:

Nastavení kopírovaného textu

Sice nelze ve všech prohlížečích standardně přímo něco nastavit uživateli do schránky, lze však ovlivnit obsah, který si zkopíruje (když kopírování sám vyvolá – Ctrl + C a podobně).

Ukázka funkční v Chrome, Firefoxu a Opeře (nefunkční v IE).

Napříč prohlížeči funkční je podstrčit uživateli jiný obsah, než se zdá, a který si potom sám zkopíruje. To se dělá tak, že při kopírovací události (oncopy) vyvolané uživatelem se vytvoří neviditelný HTML element s požadovaným obsahem – ten se standardní cestou zkopíruje – a potom už stačí jen „zahladit stopy“ (element pro kopírování odstranit, vrátit původní výběr textu a podobně).

Tento postup se používá například při přidávání zdroje do kopírovaného obsahu.

Přímé zkopírování tlačítkem

Přece jenom existuje způsob, jak přímo zkopírovat obsah do schránky ve všech prohlížečích. Přesněji řečeno pro různé prohlížeče existují různé funkční postupy.

Kopírování pomocí execCommand

Chrome 43+, Opera 29+, Firefox 41+ a IE 10+ i Edge dokáží zkopírovat do schránky text pomocí příkazu execCommand, který se používá hlavně u WYSIWYG editorů.

Před zavoláním copy je nutné nejprve označit obsah elementu, jehož obsah se bude kopírovat. Celý kód může vypadat následovně.

var element = document.querySelector('.zkopirovat');  
var range = document.createRange();  
range.selectNode(element);  
window.getSelection().addRange(range);  
document.execCommand('copy');
window.getSelection().removeAllRanges(); 

Desktopový Internet Explorer vyžaduje povolení k přístupu do schránky.

Povolení přístupu do schránky v IE

V Chrome, Opeře nebo mobilním IE se obsah zkopíruje bez dalších dotazů.

Přímé kopírování v IE

V Internet Exploreru existuje ještě jiná možnost rovnou kopírovat do schránky – přes clipboardData. Opět je vyžadováno udělení přístupu.

if (window.clipboardData) {
  clipboardData.setData("text", "Obsah ke zkopírování");    
}

Flash řešení ZeroClipboard

Napříč prohlížeči s nainstalovaným Flashem dobře funguje nástroj ZeroClipboard. Ten nad tlačítko vloží neviditelný flashový objekt, který odchytne kliknutí a dokáže zapsat obsah do schránky bez dotazování uživatele.

Jelikož podíl zařízení s nainstalovaným/povoleným Flashem klesá, klesá i podpora kopírování do schránky pomocí flashového objektu.

Nejznámnější řešení je ZeroClipboard (instrukce). Použití je jednoduché.

  1. Vytvoří se tlačítko, tomu se do atributu data-clipboard-target nastaví element, ze kterého se má brát obsah ke zkopírování (např. <input>). Případě se obsah může přímo nastavit do atributu data-clipboard-text (atribut *-target má přednost).

    <input type="text" id="policko" value="http://jecas.cz/">
    <button 
        id="copy-button" 
        data-clipboard-target="policko" 
        data-clipboard-text="http://jecas.cz/kopirovat">
        Zkopírovat do schránky
    </button>
  2. Tlačítko se potom předá funkci ZeroClipboard, která zajistí kopírování a umožní i nastavení akce po úspěšném zkopírování.

    var client = new ZeroClipboard(
      document.getElementById("copy-button")
    );
    client.on("ready", function( readyEvent) {
      client.on("aftercopy", function(event) {
        // v event.target je kopírovací tlačítko
        event.target.innerHTML = "Zkopírováno";
      });
    });
  3. Potřebný JavaScript a Flash jde kromě lokálního umístění taktéž načíst z CDN (co je to CDN?).

Samostatná ukázka.

Pro příznivce jQuery existuje nadstavba nad ZeroClipboard právě v tomto frameworku. Jmenuje se zClip.

Jak ZeroClipboard funguje?

ZeroClipboard funguje tak, že všechna propojená tlačítka překryje průhledným Flashem, který zachytne kliknutí, které způsobí uložení do schránky. Zkopírovat něco do schránky automaticky bez akce uživatele není možné.

Stavy při najetí (:focus) nebo kliknutí (:active) je nutné simulovat přes speciální třídy, které ZeroClipboard přidává.

.tlacitko.zeroclipboard-is-hover { background-color: #eee; }
.tlacitko.zeroclipboard-is-active { background-color: #aaa; }

Dynamické přidávání ZeroClipboard

Pokud při načtení stránky nevíme, které elementy má být možno kopírovat (například ještě na stránce nejsou, protože budou přidány až po nějakém AJAXovém požadavku), postup bude následující.

  1. Vytvoří se instance ZeroClipboard se společnou funkcí pro tlačítka ke kopírování (tato funkce po zkopírování do tlačítka napíše změnou innerHTML „Zkopírováno“):

    var client = new ZeroClipboard();
    client.on("ready", function(readyEvent) {
      client.on("aftercopy", function(event) {
        event.target.innerHTML = "✔ Zkopírováno";
      });
    });	
  2. Jednotlivá tlačítka se přidají funkcí clip.

    client.clip(
      document.getElementById("tlacitko")
    );

    Text ke zkopírování se vezme z atributu data-clipboard-text daného tlačítka.

    Živá ukázka

    Kromě předávání jednotlivých tlačítek to může být i kolekce elementů. Dobře se k tomu hodí querySelector (od IE 8).

    client.clip(
      document.querySelectorAll("button[data-clipboard-text]")
    );

    Živá ukázka

Co použít pro kopírování

Ze všech postupů jde poskládat relativně dobře fungující řešení pro pohodlné zkopírování jedním kliknutím napříč prohlížeči.

V novějším Chrome a Opeře je jasná volba použití execCommand. V IE je situace dost nerozhodná – použití flashového objektu bude fungovat bez nutnosti kopírování potvrdit, ale zase znamená stažení desítek kB kódu.

Ve Firefoxu 40 a starších potom nezbývá jiné řešení než Flash.

V případě, že nechceme používat řešení s Flashem, dá se řešení využívající execCommand alespoň zkombinovat s promptem pro nepodporující prohlížeče (ukázka).

Odkazy jinam