document.write in extern script in dyn. gevulde iframe

Pagina: 1
Acties:
  • 712 views sinds 30-01-2008
  • Reageer

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
Mijn situatie is dat ik een iframe element heb, die ik via javascript dynamisch vul. Dat gaat ongeveer op de manier:

HTML:
1
2
3
4
5
6
7
<iframe src="" id="cnt"></iframe>

<script type="text/javascript">
    window.frames['cnt'].document.open();
    window.frames['cnt'].document.write( 'some_content' );
    window.frames['cnt'].document.close();
</script>


Dit werkt voor de meeste content zonder problemen. Het gaat echter niet helemaal goed als ik voor 'some_content' een extern javascript aanroep dat document.write bevat.

Direct document.write gebruiken gaat wel goed. Als ik voor 'some_content' het volgende invul, dan werkt het zoals verwacht:

HTML:
1
2
3
4
5
6
7
<html><body>
   Voor write
   <script type="text/javascript">
      document.write ( ' text write ' );
   </script>
   Na write
</body></html>


Zet ik nu echter die ene javascript regel in een extern bestand, b.v. write.js en herschrijf ik 'some_content' naar het volgende, dan werkt het niet:

HTML:
1
2
3
4
5
<html><body>
   Voor write
   <script type="text/javascript" src="http://myhost/write.js" ></script>
   Na write
</body></html>


In dit laatste geval wordt het hele document in de iframe overgeschreven (in firefox 2) door die ene regel 'text write'. Dat is in dit geval niet wat ik wil. Als ik de zelfde HTML als hierboven in een losse pagina zet en die aanroep, dan overschrijft write.js niet de gehele pagina.

Nu zegt de API documentatie van document.write, dat er inderdaad een nieuw document wordt gemaakt als de pagina al geheel geladen is. In bovenstaand geval zitten we echter nog midden in de pagina. Als ik bijvoorbeeld ten hoogte van "Na write" een javascript alert() zet, wordt deze niet uitgevoerd.

Ik probeer voornamelijk te begrijpen wat hier nu precies gebeurd. Iemand enig idee?

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
Nog een interessante observatie, als ik in het externe script, voor de document.write het volgende toevoeg:

HTML:
1
alert ( "body = \n" + document.body.innerHTML );


Dan wordt er exact het document afgedrukt tot en met de javascript include, dus:

HTML:
1
2
3
<html><body>
   Voor write
   <script type="text/javascript" src="http://myhost/write.js" ></script>


Op dat moment is het dus duidelijk dat de 'pagina' nog niet in z'n geheel is geladen. Zodra ik echter de document.write doe, wordt het hele bestaande document vervangen. Als ik dezelfde alert nogmaals na de write zet dan is dat al meteen duidelijk. Het bevat dan alleen nog die ene regel die document.write schreef.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
Probeer eens:
HTML:
1
2
3
4
5
6
7
<html><body>
   Voor write
   <script type="text/javascript" src="http://myhost/write.js" >
   schrijf();
   </script>
   Na write
</body></html>

met in je remote script een functie schrijf() die dit doet. Anders kan je ook es kijken naar nedstat-code en dergelijke, die moeten vaak hetzelfde doen als jij wil.

Persoonlijk zou ik echter werken met dom-functies of get elementbyid().

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
moozzuzz schreef op woensdag 20 juni 2007 @ 18:51:
Probeer eens:
[...]
met in je remote script een functie schrijf() die dit doet.
Dat werkt helaas niet. Als ik in het externe scriptje een function schrijf(); defineer, dan wordt die op bovenstaande manier niet aangeroepen.

Doe ik echter het volgende:

HTML:
1
2
3
4
5
6
7
8
<html><body>
   Voor write
   <script type="text/javascript" src="http://myhost/write_f.js" ></script>
   <script type="text/javascript">
      schrijf();
   </script>
   Na write
</body></html>


Dan wordt ie wel aangeroepen, maar wordt het document weer in z'n geheel vervangen. Dit levert wel weer een andere dubieuze observatie op. Zoals eerder gezegd, het volgende werkte:

HTML:
1
2
3
4
5
6
7
<html><body>
   Voor write
   <script type="text/javascript">
      document.write ( ' text write ' );
   </script>
   Na write
</body></html>


Als ik nu het volgende gebruik, dan werkt het niet!

HTML:
1
2
3
4
5
6
7
8
9
10
<html><body>
   Voor write
   <script type="text/javascript" src="http://myhost/write_f.js" ></script>

   <script type="text/javascript">
      document.write ( ' text write ' );
   </script>

   Na write
</body></html>


Het bijzonder is dat write_f in dit geval alleen maar een function definition bevat die nu dus niet wordt aangeroepen. Blijkbaar triggert het feit dat er een extern script wordt geladen ergens iets wat bij de eerstvolgende document.write een nieuw document laat creëren.
Persoonlijk zou ik echter werken met dom-functies of get elementbyid().
Het feit wil dat ik de content die geschreven wordt in de iframe niet onder eigen beheer heb. Hoogstens kan ik er wat omheen zetten.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
Ik heb trouwens nog even getest met andere browsers. Opera 9 en Safari 3 op Windows doen precies wat je zou verwachten. IE 6 doet het half; de text die door document.write in het externe scriptje geschreven wordt komt helemaal aan het eind in plaats van in het midden.

Dat opmerkelijke nieuwe document aanmaken wat Firefox 2 doet blijft dus erg vreemd.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
Kan je niet alles wat je wil schrijven in een variabele gooien en die dan met intern <script> uitschrijven?

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
moozzuzz schreef op vrijdag 22 juni 2007 @ 17:25:
Kan je niet alles wat je wil schrijven in een variabele gooien en die dan met intern <script> uitschrijven?
Hoe bedoel je precies?

Wat ik wil schrijven staat ook in een variable, unescaped is dat gewoon:

HTML:
1
2
3
Voor write
   <script type="text/javascript" src="http://myhost/write.js" ></script>
Na write


Het nare is dat dat dus blijkbaar niet werkt in Firefox, terwijl het eigenlijk wel zou moeten werken.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • user109731
  • Registratie: Maart 2004
  • Niet online
Ik heb er ook even naar gekeken, en ik denk dat het volgende gebeurt: document.write() word aangeroepen, maar write.js word niet direct geladen. Dan word de document.close() eronder uitgevoerd. Vervolgens word in het iframe write.js geladen, en daarin roep je document.write() aan. Het document is echter al gesloten dus die word gewist en opnieuw geopend...

Het werkt wel als je document.close() weglaat. Ik gebruik niet exact jouw code maar het lijkt me hetzelfde probleem. Een soort race conditie dus ;)

[ Voor 10% gewijzigd door user109731 op 23-06-2007 14:52 ]


  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
JanDM schreef op zaterdag 23 juni 2007 @ 14:51:
Het werkt wel als je document.close() weglaat. Ik gebruik niet exact jouw code maar het lijkt me hetzelfde probleem. Een soort race conditie dus ;)
Ik snap wat je bedoeld, maar als je er over nadenkt, in hoeverre is deze gang van zaken verschillend met de situatie waar de content (die nu direct in het iframe wordt geschreven) wordt opgehaald via het src attribuut van de iframe?

Ook in die situatie zal er een impliciete document.close worden gedaan door de browser als de laatste byte binnenkomt (de EOF). In deze situatie doet FireFox het wel goed, met exact dezelfde content.

Wellicht dat in de 'gewone' situatie (content laden via src attr.) FireFox slim genoeg is om te zien dat er nog pending requests zijn en dus de feitelijk document.close delayed. Opera 9 en Safari 3 passen dan wellicht die zelfde logica ook toe als je handmatig content in een frame schrijft en dan expliciet document.close aanroept.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.

Pagina: 1