O webu
JS akce u odkazu

Při vytváření webové aplikace, která funguje i bez podpory JavaScriptu, se často setkáme s tím, že odkaz má normální cíl, ale v případě zapnutého JS bude obsloužen skriptem.

Pro odkaz, který bude umět načítat obsah AJAXem to může vypadat následovně:

<a href="url-stranky" onclick="nacistAjaxem(this.href)">
  Odkaz
</a>

Při použití obrázkové galerie:

<a href="velky-obrazek.jpg" onclick="otevritGalerii(this.href)">
  <img src="maly-obrazek.jpg">
</a>

Funkce v onclick potom provede JS akci a stornuje standardní funkci odkazu, třeba pomocí „return false“.

Způsob otevření odkazu

Celé to ale není tak jednoduché, odkaz jde totiž typicky otevřít více způsoby:

  1. kliknutím levého tlačítka,
  2. otevřením prostředním tlačítkem (kolečkem), což typicky otevírá obsah na pozadí,
  3. otevřením přes kontextové menu vyvolané pravým tlačítkem,
  4. kliknutím levého tlačítka při stisknuté klávese Ctrl (otevře na pozadí) nebo Shift (otevře do nového okna)

Kromě otevření přes kontextové menu vyvolají všechny případy onclick, ač by bylo očekávávané chování pro kolečko nebo použití Shift/Ctrl otevření odkazu v nové záložce (na popředí/pozadí).

Kliknutí na následující odkaz je obslouženo JavaScriptem, i když to není zrovna ideální.

Řešení

Zajistit v určitých případech standardní chování jde pomocí využití objektu event, z kterého jde zjistit číslo stisknutého tlačítka (event.which – levé tlačítko má číslo 1) nebo stisknuté klávesy (event.shiftKey || event.metaKey || event.ctrlKey).

JS akce se vyvolá pouze při levém tlačítku

Samostatná živá ukázka

Akce bez URL

Problém nastane u JS akcí, které nemají URL. Při touze otevřít odkaz na pozadí zkrátka neexistuje URL, kterou by prohlížeč mohl nalistovat.

Pokud akce nemá URL, asi nejmenší zlo se mi zdá použít obyčejný onclick a jako cíl odkazu uvést alespoň nějakou URL, což bude lepší než prázdná stránkaabout:blank“, která se otevře u odkazů typu:

<a href="javascript:akce()">
  Odkaz
</a>

Případně přidat do JS aplikace fiktivní URL není s využitím pushState zase takový problém.