Méně známé HTML5 API, 2. část

JavaScript, HTML

V druhém díle seriálu se podíváme, jak lze rozvibrovat telefon, kopírovat do schránky nebo zaznamenávat odchod ze stránky.

HTML5 API, 2. část

Méně známé HTML5 API, 1. část: Fullscreen, Page Visibility, Performance
Méně známé HTML5 API, 2. část: Vibration, Clipboard, Beacon
Méně známé HTML5 API, 3. část: Feature Queries, Device Orientation/Motion

V minulém díle jsme se letmo věnovali Fullscreen, Page Visibility a Performance API. Dnes se podíváme na API zaměřené specificky na mobilní zařízení - Vibration. Dále letmo představíme Clipboard, které umožňuje pracovat se schránkou operačního systému. A na konec zmíníme malé signální Beacon API, užitečné pro zasílání dat při odchodu ze stránky.

Vibration

Ryze na mobilní zařízení zaměřená Vibration je taková jednohubka mezi API. V objektu navigator vystavuje jedinou metodu vibrate. Ta přijímá jediný argument - délku vibrace nebo pole délek vibrací a mezer.

// Vibruje 500 ms
navigator.vibrate(500)

V příkladu se zařízení prostě rozvibruje po danou dobu. Pokud zařízení neumí vibrace, nestane se vůbec nic.

Když je ale v argumentu pole, funguje to trochu jinak. V takovém případě jdou za sebou střídavě vždy délka vibrace a délka pauzy.

// Vibruje SOS signál
// Od začátku: 100 ms vibrace, 30 ms pauza, 100 ms další vibrace, atd.
const sos = [100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100]
navigator.vibrate(sos)

Vyzkoušet si to můžete v příkladu.


Vibrace jdou předčasně zastavit zavoláním metody s nulovou délkou, prázdným polem nebo polem obsahujícím jen nuly.

// Zastaví vibrace dříve
navigator.vibrate(0)
navigator.vibrate([])
navigator.vibrate([0, 0, 0])

Prohlížeče s podporou jsou momentálně Chrome pro Android, Firefox Mobile a Opera Mobile. Na Safari si, bohužel, nezavibrujete. Pro zajímavost si můžete vyzkoušet, například zde, jaké melodie jde s pomocí vibrací vytvořit.

Clipboard

Základní úkony jako kopírování a vložení,  zvládá každý operační systém. Na webu jsme ale byli dlouhou dobu odkázáni na bohem zapomenutý Flash. To už naštěstí neplatí a tak můžeme vesele kopírovat pomocí Clipboard API.

Práce s Clipboard má svá pravidla. Kopírovat lze pouze výběr a podobně jako u Fullscreen API musí být kopírování vyvoláno uživatelským vstupem (například kliknutím).

// Metoda execCommand vrací true pokud se povedlo příkaz provést
// Zkopíruje aktuálně vybraný text do schránky
const isCopied = document.execCommand('copy')

// Vyjme aktuálně vybraný text např. z textarea do schránky
const isCopied = document.execCommand('cut')

Naštěstí existují možnosti, jak provést výběr aniž by uživatel musel nějaký text označovat. Nejjednodušeji toho dosáhneme použitím elementu input nebo textarea. Ty mají metodu select, která označí do výběru jejich obsah.

const copyInput = document.querySelector('#copy-input')


// Je podpora pro execCommand('copy') ? 
if (document.queryCommandSupported('copy')) {

    // Vybere text v inputu
    copyInput.select()

    // Zkopíruje výběr do schránky
    if (document.execCommand('copy')) {
        console.log('Text byl zkopírován.')
    }
    else {
        console.log('Při kopírování došlo k chybě.')
    }
}

Podobný příklad si můžete vyzkoušet v ukázce.

Co když nechci použít input ani textarea? V takovém případě si můžeme pomoci Selection API. To je sice mimo záběr tohoto článku, ale pokud si chcete přečíst více, je dobře popsané v dokumentaci MDN. S jeho pomocí můžeme vytvořit výběr textu na libovolném prvku.

const copyLink = document.querySelector('a#copyLink')

// Je podpora pro execCommand('copy') ?
if (document.queryCommandSupported('copy')) {

    // Vytvoří výběr na daném prvku
    const range = document.createRange()
    range.selectNode(copyLink)
    window.getSelection().addRange(range)
 
    // Zkopíruje výběr do schránky
    const isCopied = document.execCommand('copy')
 
    // Zruší náš výběr
    window.getSelection().removeRange(range)
}

Příklad si můžete vyzkoušet v ukázce.

Kromě samotného kopírování jsou součástí Clipboard API i eventy spouštěné při vkládání do, nebo kopírování ze stránky. S jejich pomocí lze manipulovat s vkládánými daty a např. vložit zkopírovaný obrázek do stránky. Více si můžete přečíst v dokumentaci ClipboardEvent.

Prohlížeče od IE 10+ uvádějí částečnou podporu. To znamená, že by měly zvládat hlavně copy, cut a korespondující eventy. Pro komplexnější práci doporučuji miniaturní knihovnu clipboard.js, která je kolem tohoto API postavená.

Beacon

Záznam opuštění stránky uživatelem dříve mohl být (a ve starších prohlížečích stále je) nepříjemnou zkušeností. Na odchod ze stránky je možné reagovat v eventu unload. Pokud chcete v takovou chvíli poslat záznam s daty na server, musíte trochu slevit z nároků. V unload eventu prohlížeče totiž většinou ignorují asynchronní požadavky. To však má jednoduché řešení - nastavením třetího argumentu XmlHttpRequestu pošleme požadavek synchronně.

// Starý způsob zasílání dat při opuštění stránky
window.addEventListener('unload', () => { 
    const xhr = new XMLHttpRequest()
    const data = JSON.stringify({
        log: 'Ukázkové data',
        timestamp: Date.now()
    })
    xhr.open('post', '/api/log.php', false)
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.send(data)
})

Což funguje, ale do ideálního řešení to má daleko. Synchronním požadavkem blokujeme dokončení uzavření stránky. Prohlížeče na to reagují různě a výsledkem může být zpomalené načítání nové stránky se kterým daná stránka nezmůže vůbec nic.

Z toho důvodu bylo vytvořeno Beacon API. Umožňuje poslat asynchronní POST požadavek, který zavření stránky nijak neblokuje, je spolehlivý a nečeká žádnou odpověď. Jeho použití je velmi jednoduché.

window.addEventListener('unload', () => { 
    const data = JSON.stringify({ 
        log: 'Ukázkové data', 
        timestamp: Date.now() 
    })
    navigator.sendBeacon('/api/log.php', data); 
})

Beacon není vázán na unload event. Použít jej samozřejmě můžete kdekoliv, kde potřebujete odeslat krátký požadavek a neočekáváte odpověď. Obecně je ale navržen pro jednu specifickou věc. Používají jej napříkladGoogle Analytics, pokud to prohlížeč podporuje, a mají nastavený parametr useBeacon.

API má v době psaní tohoto článku podporu novějších verzí Edge, Chrome, FF a Opery. Safari jej podporuje až od verze 11.1 a Internet Explorer je úplně mimo hru. Zatím je tedy dobré podporu kontrolovat a případně počítat s fallbackem na synchronní požadavek nebo podobné metody. Další informace najdete v dokumentaci MDN nebo třeba v tomto článku na jecas.cz.

if (navigator.sendBeacon) {
    // Použij Beacon API ...
}
else {
    // Fallback ke starším metodám ...
}

A jak vy řešíte kopírování do schránky? Napadá vás i jiné využití Beacon API? Podělte se v komentářích.

K tomuto článku již není možné přidávat další komentáře