O webu
Spuštění JS načteného AJAXem

S využitím history.pushState a změnou URL bez znovunačtení stránky není problém celý web načítat AJAXem.

Jeden menší problém ale AJAXem stahovaný obsah má – vykonání skriptů ve značce <script>.

Stránka obsahující následující skript, který nastaví barvu jejího odstavce na červenou, se po načtení AJAXem nevykoná.

<p>Stránka</p>
<script>
  document.querySelectorAll("p")[0].style.color = "red";
</script>

Příkaz eval

Callback funkce pro nastavení obsahu stránky, která dostane obsah AJAXem získané stránky, může vypadat následovně:

function vypsat(data) {
  var obsah = document.getElementById("obsah");
  obsah.innerHTML = data;
  // oživení skriptů
  var scripty = obsah.getElementsByTagName('script');
  for (var i = 0; i < scripty.length; i++) {
    eval(scripty[i].innerHTML);			
  }
}

Na začátku se nastaví asynchronně získaný obsah do elementu #obsah. V něm se následně najdou značky <script> a jejich kód se provede pomocí evalu.

Odstavec z předchozí ukázky už bude červený.

Volání funkce

Co ale v případě, že bude mít stahovaná stránka ve značce <script> definici funkce, která se má později volat:

<p>Stránka</p>
<script>
  function naCerveno() {
    document.querySelectorAll("p")[0].style.color = "red";
  }
</script>
<button onclick="naCerveno()">Načerveno</button>

Použití evalu proměnnou/funkci naCerveno nevytvoří.

Nedefinovaná proměnná

Vytvoření <script>u

Další možnost je dynamicky vytvořit nové značky <script>, vložit do nich příslušný kód a přidat je do stránky:

// Vytvoření značky
var novyScript = document.createElement("script");
// Nastavení obsahu skriptu do innerHTML
novyScript.innerHTML = scripty[i].innerHTML;
// Přidání skriptu do stránky
document.body.appendChild(novyScript);

Celý kód:

function vypsat(data) {
  var obsah = document.getElementById("obsah");
  obsah.innerHTML = data;
  // oživení skriptů
  var scripty = obsah.getElementsByTagName('script');
  for (var i = 0; i < scripty.length; i++) {
    var novyScript = document.createElement("script");
    novyScript.innerHTML = scripty[i].innerHTML;
    document.body.appendChild(novyScript);
  }
}

Při tomto postupu není problém s voláním definované funkce.

Skript v <img onload>

Bez nutnosti procházet na stránce jednotlivé skripty a oživovat je se dá využít umístění skriptu do on* atributu, který se sám zavolá.

K tomu jde použít událost onload u obrázku. Pokud se jako src uvede soubor, který se stejně načítá, nezpůsobí to ani zbytečné stahování dat.

<img src="logo.png" onload="// JS kód">

Použít by šla i událost onerror, ale bylo by kvůli ní nutné načíst něco neexistujícího.

Onload jde použít pouze ke spuštění nadeklarované funkce. V něm vytvořené funkce by se musely přiřazovat do window, aby byly dostupné:

onload="window.naCerveno = function() {…}"

Oddělení JS a HTML

Někteří lidé zastávají myšlenku striktního oddělení HTML kódu a JavaScriptu.

JS funkce jsou ve zvláštním souboru a jednotlivým elementům jsou až následně přiřazovány.

element.onclick = naCerveno;

Skript si tedy nejprve najde potřebný element a nastaví mu, co má dělat při požadované události.

Při tomto postupu stačí na AJAXem vypsaný obsah všechny události navázat.