Kanon bog(!), men den må så være skrevet i 2005/6. Den er en anelse yngre end De Ti Bud! *o)
Det er et kæmpe emne, som omfatter mange forskellige problematikker i forskellige browsere og deres forskellige versioner - ikke mindst IE. Specielt har IE haft meget svært ved at rydde ordentligt op - eller rettere, at koordinere oprydningen af JavaScript med oprydningen af DOM'en og omvendt. IE har således haft enormt svært ved at opløse cirkulære referencer mellem JavaScript scopes og DOM elementer, hvilket dog er blevet væsentligt forbedret i de seneste 2-3 versioner.
Det er dog ikke kun fejl og uhensigtsmæssigheder i browserne, der skaber problemer. Ligeså ofte skyldes problemer omkring memory leaks manglende forståelse for DOM og JavaScript - og såmænd også mangel på grundlæggende forståelse for programmering og programmel.
I den følgende kode oprettes en reference til to
DIV på
onload. Derefter farver jeg det inderste
DIV gult og indsætter et
P element med
innerHTML, når der trykkes på den første knap.
Et klik på den anden knap prøver at farve det inderste
DIV rødt, men hvad sker der?
Tredie knap prøver at sammenligne referencen, jeg oprettede på
onload med det
DIV, der ligger i dokumentet. Hvad sker?
<script type="text/javascript">
var elmInner = null,
elmOuter = null;
function foo() {
elmInner.style.background = "#ff0";
elmOuter.innerHTML += "<p>Et P-tag, indsat med innerHTML</p>";
}
function bar() {
// Dette virker ikke
elmInner.style.background = "#f00";
}
function baz() {
// Er elmInner og vores DIV 'inner' det samme?
alert(document.getElementById("inner") == elmInner);
}
window.onload = function() {
elmInner = document.getElementById("inner");
elmOuter = document.getElementById("outer");
}
</script>
<div id="outer">
<div id="inner">Dette er DIV'et "inner"</div>
</div>
<p>
<button onclick="foo()">Tilføj og farv 'inner' gul</button>
<button onclick="bar()">Farv 'inner' rød</button>
<button onclick="baz()">Er de ens?</button>
</p>
Når vi skriver noget til i det yderste DIV's
innerHTML, overskriver vi i virkeligheden denne med en kopi af sig selv - plus det nye. Derfor er det inderste
DIV ikke længere det samme, som det, vi lavede en reference til på
onload.
Det ligger til gengæld i hukommelsen - og er ildrødt *o)
Faktisk kan du prøve at sætte det ind igen med:
function fooBar() {
elmOuter.appendChild(elmInner);
alert(elmOuter.innerHTML)
}
- og:
<button onclick="fooBar()">Indsæt igen</button>
Alert'en er kun til, fordi DIV'et i hukommelsen er tomt i IE og derfor ikke bliver vist ... men det ligger der. Alle andre browsere viser DIV'et med oprindeligt indhold.
En enkelt reference, der bliver liggende i hukommelsen, betyder ikke noget, men i moderne objekt orienterede, dynamiske, ajax drevne applikationer kan det pludselig blive rigtig meget hukommelse, der ikke frigives.
Et andet eksempel er manglende brug af nøgleordet
this i event handlers. Et eksempel kunne være:
var oXHR = new XMLHttpRequest();
oXHR.open("post", sUrl, true);
oXHR.setRequestHeader("Content-Type: application/x-www-form-urlencoded; charset=utf-8");
oXHR.onreadystatechange = function() {
if (oXHR.readyState<4) return;
doSomeThing(oXHR.responseText);
};
oXHR.send("contxt=getUsers");
Her oprettes en cirkulær reference mellem JS og XHR-objektet, fordi variabelnavnet '
oXHR' benyttes indenfor handlerens closure. Denne reference opløses ikke ved funktionens udløb i IE - i hvertfald ikke op til og med version 8. Det siges, det skulle være rettet helt i version 9, men jeg har ikke selv fået testet.
Løsningen er at bruge
this i stedet for
oXHR indenfor handleren - hvilket også er i langt bedre overensstemmelse med almindelig OOP-tankegang.
Der ligger enkeltartikler om emnet her og der på nettet, men husk at tjekke for alderen. Der er kæmpe forskel på specielt IE6-9 - med mange mellemstadier.
Meget af det grunder dog som sagt i forståelse af virkemåden af browseren , DOM'en og JavaScript - samt programmering, generelt. Webkodning har en flad indlæringskurve. Ligesom det i sløjdsalen er forholdsvis let at få lavet noget brugbart, kan man også skrive alm. websider med noget serverdrevet dynamik.
Når man skal i gang med at skrive dynamiske webapps med Ajax og masser af DOM manipulation, kommer man til det punkt, hvor møbelsnedkeren skiller sig ud fra sløjdsalen. Moderne webudvikling er et fag *o)