Kruse-Net.dk

Det man blogger er man selv…

Brug af script.onload

En fiks måde asynkront at loade JSON data i en AJAX applikation på er:

var script = document.createElement('script');
script.type = "text/javascript";
script.src = "http://enurl";
document.getElementsByTagName('head')[0].appendChild(script);

Hvis man også ønsker at vide hvornår script’et er loadet, og ens data dermed er klar, kan man blot tilføje følgende linie et sted i midten:

script.onload = function() { alert('data er klar!'); } // eller en anden funktion efter eget valg

Det virker fint i browsere der bare overholder standarderne nogenlunde. I Internet Explorer (testet på version 6) er der dog et par fælder man skal være opmærksom på!

  1. Hvis IE før har loadet et script fra samme URI, så kontaktes serveren slet ikke. I nogle tilfælde er det fint (data fra sidst indlæses fra cachen), i andre tilfælde skal serveren altid kontaktes, hvilket man kan sikre ved at lave om på URI’en.
  2. IE loader script’et i samme øjeblik src attributten sættes. Det kan ikke forhindres, så det skal man bare være opmærksom på.
  3. onload attributten virker bare ikke i IE. Funktionen bliver aldrig kaldt! Til gengæld virker onreadystatechange fint i IE.

Script’et der tager højde for ovenstående fælder ser således ud:

// Denne funktion er vores event handler
function dataReady() {
  if (!script.readyState || script.readyState == 'loaded') {
    alert('data er klar!');
  }
}

// Vi lægger objektet i en global variabel for at have enkel adgang til det fra event handleren
var script = document.createElement('script');
document.getElementsByTagName('head')[0].appendChild(script);
script.onload = dataReady;
script.onreadystatechange = dataReady;
script.type = 'text/javascript';
script.src = 'http://adressen.til/min/script/service' + '?_=' + (new Date()).getTime();

Det antages i ovenstående løsning at browsere der understøtter onreadystatechange også understøtter egenskaben readyState. For disse browsere vil dataReady() sandsynligvis blive kaldt flere gange mens script’et loades. Derfor reagerer funktionen kun sidste gang, hvor readyState = 'loaded'.

Øvrige browsere kender ikke readyState egenskaben. For dem reagerer funktionen første gang den kaldes (hvilket meget gerne skulle være “onload”).

Jeg har testet i Firefox 1.5.0.5 og Internet Explorer 6.0.2900.2180.

Skriv et svar