Tentokrát opravdu dynamické HTML

21. ledna 2010

Chystaná specifikace HTML 5 posunuje možnosti vývojářů webových aplikací na hranice, o nichž se průkopníkům DHTML v roce 1997 snad ani nesnilo.

Přehrávání audiovizuálních souborů

Původně měly webové stránky pouze textový obsah. To ovšem trvalo jen krátce, vývojáři prohlížečů překotně ochotně vyšli vstříc kreativním tvůrcům a krom jiného jim umožnili vkládat do stránek různé externí objekty. Na scéně se tak objevily i elementy bgsound a embed, které stránky obohacovaly o zvuky a videa. W3C později přišlo ještě s elementem object. (A aby toho nebylo málo, tak přibudou ještě elementy audio a video.)

Multimediální objekty se přehrávaly prostřednictvím pluginů. Nebyl-li příslušný plugin do prohlížeče zabudovaný či dodatečně instalovaný, tak přehrávání nefungovalo. Podrobně celou problematiku tehdy rozebral Dušan Janovský. Od té doby se situace značně zlepšila, prohlížeče všeobecně podporují flash (ani v operačních systémech na bázi Linuxu nebo Unixu to nepředstavuje významnější problém, jejich uživatelé si umí potřebný plugin doinstalovat) a ten zase podporuje spoustu audiovizuálních formátů. Takže stačí „zabalit“ video nebo hudební soubor do flashe a flash vložit do stránky. Ve flashi lze navíc vytvořit vlastní elegantní ovládací prvky, které budou stejné ve všech prohlížečích. Tento postup má však tři nedostatky.

  1. Je potřeba použít flash, což představuje nadbytečný mezikrok
  2. Problém s přístupností
  3. Přehrávání nelze ovládat skriptem

Kdybychom se těmto nepříjemnostem snažili předejít tím, že bychom se vyhnuli flashi a vkládali multimediální objekty přímo, zjistili bychom, že jsme se dostali takříkajíc z bláta do louže. V současnosti prostě žádné řešení není spolehlivější než to flashové. V budoucnu by tomu však mělo být jinak. Podle návrhu specifikace HTML 5 budou integrální součástí webových prohlížečů audiovizuální přehrávače, zastoupené elementy audio a video. To by elegantně vyřešilo všechny potíže způsobené tím, že prohlížeče přehrávání nechávají na externích aplikacích. Zároveň by takový přehrávač byl plnohodnotně ovladatelný pomocí JavaScriptu, což by z praktického hlediska mělo ten nezanedbatelný význam, že by bylo možné jednak pro přehrávání multimediálních objektů i bez flashe vytvářet vlastní uživatelská rozhraní s líbivým designem, stejným ve všech prohlížečích, a jednak nesmírně snadno doplnit javascriptové aplikace o zvukové efekty.

Elementy audio a video mají v HTML tyto atributy:

  • src – Pro zadání URL zdroje (např. písničky ve formátu MP3 nebo streamovaného videa)
  • autobuffer – Vyjadřuje víru autora stránky, že uživatelé budou chtít zdroj zaručeně přehrát. Prohlížeče ale nejsou povinné zdroj přednostně načíst.
  • autoplay – Automatické přehrání zdroje
  • loop – Po přehrání zdroje návrat na začátek
  • controls – Zobrazení panelu s ovládacími prvky
  • poster – URL obrázku, který prohlížeč může zobrazit místo videosnímku, než se video začne načítat
  • Globální atributy – id, class atp.

Ostatní vlastnosti, např. readyState (vrací 4, je-li získáno dost dat k přehrávání), error (vrací číslo; 0 – v pořádku, 1 – požadavek nebyl odeslán, 2 – problém na síti, 3 – nelze dekódovat, 4 – nevyhovující zdroj), duration (zjišťuje, jak dlouho bude přehrávání trvat, vrací počet sekund), currentTime (nastavuje nebo zjišťuje pozici playbacku, hodnotou počet sekund), volume (0.0 – nejtišší, 1.0 – nejhlasitější), playbackRate (rychlost přehrávání, výchozí hodnotou 1.0), muted, played, paused, ended a další, jakož i metody canPlayType(MIME_typ), load(), play() a pause(), jsou přístupné přes DOM – ukážeme si to.

function createPlayer() {
  //přidat do stránky element audio
  var zvuk = document.createElement("audio");
  zvuk.setAttribute("src","sound.wav");
  zvuk.load();
  zvuk.onload = function() {
    var trvani = "Zvuk se bude přehrávat " + Math.round(zvuk.duration) + " s";
    spustit.setAttribute("title",trvani);
  };
  //přidat do stránky tlačítko pro spuštění
  var spustit = document.createElement("img");
  spustit.setAttribute("src","play.png");
  spustit.setAttribute("alt","Spustit");
  spustit.onclick = function() {zvuk.play()};
  document.body.appendChild(spustit);
  //přidat do stránky tlačítko pro pozastavení
  var pauza = document.createElement("img");
  pauza.setAttribute("src","stop.png");
  pauza.setAttribute("alt","Pozastavit");
  pauza.onclick = function() {zvuk.pause()};
  document.body.appendChild(pauza);
}

Na příkladu funkce createPlayer() (příklad funguje v prohlížeči Mozilla Firefox 3.5) jsme si předvedli, jak snadné bude vložit na stránky hudební přehrávač. Pravda, tenhle je dost primitivní, ale dá se zdokonalit.

Nyní se podíváme ještě na události (events), které se vážou k přehrávání multimediálních objektů. Nabízí se jich celkem dost: loadstart, progress, suspend, abort, error, emptied (tato událost vzniká buď v důsledku chyby, nebo když je metoda load() volána vícekrát), stalled, play, pause, loadedmetadata, loadeddata, waiting, playing (na rozdíl od události play, vzniká i po přesunutí playbacku), canplay, canplaythrough, seeking, seeked, timeupdate, ended, ratechange, durationchange, volumechange.

Přehrávání může probíhat i selektivně. Selektivně v tom smyslu, že by se z celého videa nebo alba přehrály jen vybrané streamy či klipy. Bude dokonce možné díky rozhraní TimeRanges definovat jen určité, libovolně dlouhé úseky a ty pak přehrát.

Nové možnosti, které byly v této kapitole popsány, mohou u programátorů webových aplikací právem budit nadšení, ale pozor, jak už psal Dušan Janovský, asi ne každý radostně ocení, když se mu z nenadání na celou kancelář z „repráků“ rozezní nějaký jekot. Je třeba si také uvědomit, že řada uživatelů při práci poslouchá hudbu, a zvuky z webových stránek by se do ní míchaly.

Přetahování objektů

Uživatelé, zvláště ti pokročilejší, techniku drag and drop (táhni a pusť) při práci s počítačem rádi používají. Je to rychlé a pohodlné. Tato technika se dá pomocí JavaScriptu napodobit i na webu. Není to ovšem dokonalé. Stává se někdy na webových stránkách, že se uchopený objekt při prudkém pohybu myši vysmekne na okamžik zpod kurzoru. Slabší počítače totiž ne vždy dost rychle zvládnou provést algoritmus, který synchronizuje pozici přesunovaného objektu s pozicí kurzoru. Také nelze spolehlivě zajistit změnu podoby kurzoru ihned po „upuštění“ objektu. Za nedlouho by však takovéto komplikace měly patřit minulosti. Zaslouží se o to HTML 5. V této rozsáhlé specifikaci je krom jiného taky navrženo rozhraní, které celou věc technicky zjednodušuje a zkvalitňuje.

Prvním krokem programátora, který hodlá svou webovou aplikaci doplnit o drag and drop mechanismus, musí být deklarování přetáhnutelných objektů. K tomuto účelu poslouží atribut draggable, viz následující příklad. U obrázků (element img) a odkazů (element a s atributem href) je draggable dán implicitně.

<h3>Seznam účastníků příštího MS v kopané</h3>
<ul ondragstart="dragStartHandler(event)">
<li draggable data-value="Brazilci">Brazílie</li>
<li draggable data-value="Italové">Itálie</li>
<li draggable data-value="Slováci">Slovensko</li>
 <!-- Ostatní účastníci se odhlásili -->
</ul>

V uvedeném příkladu jsme si mohli všimnout, že do HTML kódu byl vložen i posluchač (event listener) pro událost dragstart. Ten slouží pro volání funkce (event handler), která uloží data do objektu DataTransfer. A zde je příklad oné funkce.

var internalDNDType = 'text/x-example'; // formát dat
  function dragStartHandler(event) {
  if (event.target instanceof HTMLLIElement) {
    event.dataTransfer.setData(internalDNDType, event.target.dataset.value);
    event.effectAllowed = 'move';
  } else {
     event.preventDefault();
  }
}

Tento příklad mohl být pro někoho trošku náročnější, a tak si jej rozebereme podrobněji. Na začátku dané funkce stojí podmínka, která kontroluje, zda událost dragstart opravdu vznikla na elementu li. Pokud ne, zabrání se tažení objektu. V opačném případě proces pokračuje – data se prostřednictvím metody setData() uloží do objektu DataTransfer a pomocí vlastnosti effectAllowed se inicializuje feedback. Ještě k použitým argumentům metody setData(): první argument určuje formát dat (text/x-example; prostě text) a druhý představuje získaná data, v tomto případě hodnotu atributu data-value toho elementu, na kterém byla zaznamenána událost.

Nutno ještě dodat, že element, z něhož byla data získána, nebude po úspěšném přesunu těchto dat ze svého místa odstraněn. Pokud by tak programátor zamýšlel, musel by do kódu ještě přidat posluchače pro událost dragend a navázat na něj funkci, která by odstranění daného elementu provedla. Vypadala by zřejmě nějak takto:

function dragEndHandler(event) {
  event.target.parentNode.removeChild(event.target);
}

Získaná data je potřeba někam zase vložit. Popíšeme si proto nyní fázi Drop.

<p>Mým favoritem jsou <strong ondragenter="dragEnterHandler(event)" ondragover="dragOverHandler(event)" ondrop="dropHandler(event)">...</strong>!</p>

Automatickou reakcí na události dragenter a dragover je zamítnutí elementu, u něhož k událostem došlo, jako potenciálního cíle pro vložení dat. Tomu je nutné zabránit, stane se tak příkazem event.preventDefault();. Při té příležitosti se může nastavit i dropEffect.

var internalDNDType = 'text/x-example';
function dragEnterHandler(event) {
  // podmínka ověřuje, zda se jedná o očekávaný typ dat
  if (event.dataTransfer.types.contains(internalDNDType))
    event.preventDefault();
  }
  function dragOverHandler(event) {
    event.dataTransfer.dropEffect = 'move';
    event.preventDefault();
}

Samotné vložení dat už bude triviální:

function dropHandler(event) {
  var data = event.dataTransfer.getData(internalDNDType);
  event.target.textContent = data;
}

Data, se kterými operujeme, musí přirozeně být v nějakém formátu. V použitých příkladech byl tímto formátem text/x-example. Proč zrovna tak pofidérní MIME typ, když se jednalo jenom o prostý text? Proč ne klasický text/plain? Že by snaha být originální? Přesně tak! Unikátní formát dat je pojistkou, která má zaručit, že na určené místo budou vkládána právě taková data, která tam náleží, a nikoliv třeba myší označený a přetažený text.

Vlastnosti a metody objektu DataTransfer:

  • dropEffect – určuje feedback pro druh vybrané operace, možné hodnoty: none, copy, link, move
  • effectAllowed – inicializuje feedback pro druh zamýšlené operace, možné hodnoty: none, copy, copyLink, copyMove, link, linkMove, move, all, uninitialized
  • types – vrací seznam obsažených formátů
  • clearData(formát) – maže data daného formátu; není-li formát udán, maže všechno
  • setData(formát, data) – přidává data, viz výše uvedený a popsaný příklad
  • getData(formát) – vrací data daného formátu
  • files – vrací seznam souborů uložených v objektu DataTransfer
  • addElement(element) – přidává nový feedback
  • setDragImage(element, x, y) – nastavuje feedback; prvním argumentem je element, dalšími pozice vůči kurzoru

A ještě seznam událostí v procesu drag and drop: dragstart, drag, dragenter, dragover, dragleave, drop, dragend

Malování skriptem

Element canvas představuje na webové stránce jakési „malířské plátno“, na němž lze skriptem ztvárnit takřka cokoliv, například červený čtverec. Mezi počáteční a koncový tag elementu lze vložit alternativní obsah.

Canvas samozřejmě nemůže nahradit rozvinutou a všestrannou technologii flash, nicméně pro interaktivní generování různých grafů, diagramů a jednoduchých obrázků bychom stěží našli něco lepšího. Nefunguje však v IE 8. Původně byl vyvinut firmou Apple pro Dashboard v Mac OS X a později implementován do Safari. Prohlížeče založené na jádře Gecko 1.8 a novějších, například Firefox 1.5, jej již také podporují.

O canvasu už se hodně psalo, jeden tutoriál byl přeložený i do češtiny.

Štítky: Články, HTML

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *