28. oktober 2010 - 12:10Der er
11 kommentarer og 1 løsning
IE evaluerer script-tags inden de indsættes i DOM
Hej eksperter
Se følgende:
function f(){ var frag = document.createDocumentFragment(); var s = document.createElement('script'); frag.appendChild(s); alert('set text'); s.text = "alert('dynamic');"; alert('append fragment'); document.body.appendChild(frag); alert('done'); };
Rækkefølgen på mine alerts burde være: 1. set text 2. append fragment 3. dynamic 4. done
Men i IE er den: 1. set text 2. dynamic 3. append fragment 4. done
Dvs. at Internet Explorer evaluerer mine scripts inden de bliver indsat i DOM. Hvordan får jeg Internet Explorer til at vente med at evaluere scripts før de er indsat i DOM?
Det skal bruges til at parse HTML og JavaScript om til et DocumentFragment, som derefter kan indsættes og vil udføre JavaScript gennem DOM i stedet for brug af eval().
jeg vil næsten anbefale at du kigger på om ikke det er noget JQuery kan løse for dig, for den kan lave næsten alt arbejdet, så du mere skal tænke på hvad du vil have, mere end hvordan det skal virke.
Så er jQuery blevet testet, og det var et skridt bagud, selv i Firefox. Kigger man ned i koden til jQuery, så ses det tydeligt at script-tags pilles ud af DOM, og lægges direkte i <head>-tagget ved brug af append(). Så de bliver også udført før elementet rent faktisk indsættes i document.
Følgende er prøvet med jQuery 1.4.3: function f() { alert('createElement'); var div = $(document.createElement('div')); alert('setup string'); var s = '<'+'div><'+'script type="text/javascript">alert("dynamic")<'+'/script><'+'/div>'; alert('append text'); div.append(s); alert('append to body'); document.body.appendChild(div[0]); alert('done'); };
Hvis vi skulle følge standarderne så skulle rækkefølgen være: 1. createElement 2. setup string 3. append text 4. append to body 5. dynamic 6. done
Men med jQuery ser det ud som følger: 1. createElement 2. setup string 3. append text 4. dynamic 5. append to body 6. done
Og kigger man i DOM efterfølgende, så er script-tagget ikke indsat - så jQuery virker ikke til formålet. Jeg har ikke gidet at tjekke det i IE, da jeg kan se i koden at resultatet vil blive det samme.
med henvisning til din kode: var div = $(document.createElement('div')); alert('setup string'); var s = '<'+'div><'+'script type="text/javascript">alert("dynamic")<'+'/script><'+'/div>'; alert('append text'); div.append(s);
Du laver et document.createElement('div')); Denne opretter en ny div i DOM, og når du så kører div.append(s), så afvikler den det der står i div, så du får "dynamic" og der er jo også rigtigt. Når du så i næste linie skriver alert('append to body') så kommer den jo efter at du har oprettet elementet, og derfor efter dynamic.
Jeg beklager, men det desværre forkert hvad du skriver. Når jeg kører document.createElement('div'), så får jeg et nyt div som ikke er indsat nogen steder. Der ligger ikke i DOM, men kun som en variabel i javascript. Derefter sætter jeg teksten ind i mit div-tag (som stadig ikke ligger noget sted i DOM). Først når der bliver kaldt appendChild på en node som ligger i DOM, så skal script-tagget udføres.
Prøv selv følgende i Firefox, chrome eller safari: var s = document.createElement('script'); s.setAttribute('type', 'text/javascript'); s.appendChild(document.createTextNode("alert('test');")); var div = document.createElement('div'); div.appendChild(s); setTimeout(function(){ alert('før append'); document.body.appendChild(div); alert('efter append'); }, 2000);
Rækkefølgen på dine alerts bliver: 1. før append 2. test 3. efter append
Hvis jeg gør noget lignende med jQuery, så bliver rækkefølgen: 1. test -- vent to sekunder - 2. før append 3. efter append
men du initialiserer et objekt af typen div i dit document. Du tilknytter det ikke som et child til noget andet object i document endnu, men ikke desto mindre initialiserer du det, og derfor bør det jo eksistere i DOM, bare ikke som child af noget object.
Jeg forsøger at lave ajax-navigation i et system. Mit response er html-data, incl <!DOCTYPE>, <html>, <head> etc. Herefter skiller jeg mit response ad med en regexp så jeg får det der står i spørgsmålstegnene: <title>?</title>, <body class="?"> og <body>?</body>.
Herefter overtager et eller flere callbacks som jeg ikke nødvendigvis kender, der kan pille i strukturen. Her er et af mine callbacks tilfældigvis at pille script-tags fra som har en src-attribut:
var scripts = fragment.getElementsByTagName('script'); for (var i = scripts.length-1; i >= 0; i--) if (scripts[i].getAttribute('src')) scripts[i].parentNode.removeChild(scripts[i]);
Hvis scripts udføres med eval, eller forkerte steder i DOM, vil f.eks. et document.write()-statement give en blank side, derfor skal script-tags indsættes korrekt. Der bliver desuden gjort brug af nogle attributter på mine script-tags, så der kan laves referencer i DOM, afhængig af hvor tagget ligger, derfor er placeringen på tagget også vigtig.
så vidt jeg kan se, så indlæser du dit response i document, og så arbejder du videre på det. Hvorfor arbejder du ikke med det som XML, og formaterer det korrekt inden du indlæser det som element på siden?
Hvad skulle det hjælpe? Skulle jeg så hellere lave XML-nodes i stedet? Hvis jeg indsætter dom-nodes fra et andet document, så vil mine script-tags aldrig blive udført.
Lukker. Løste problemet ved et hack hvor jeg først indsætter teksten i script-tagsne efter alt andet er sat ind.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.