Evaluating SCRIPT block in DHTML: document.write() problem

Discussion in 'Javascript' started by ethandbrown@gmail.com, Jun 24, 2006.

  1. Guest

    Hi All--

    I'm a bit stymied here. I need to display arbitrary HTML obtained
    through AJAX. The problem is when a <script> block is encountered
    one can't use innerHTML to set the content, because the <script> block
    won't be evaluated.

    Googling around, a found the createContextualFragment() solution
    which does execute script code. The following, for example, works:

    var content = "<SCRIPT language='javascript' type='text/javascript'>" +
    "\n"
    + 'alert("Hello")' + "\n"
    + '</SCRIPT>' + "\n";

    function fillDiv()
    {
    var mydiv = document.getElementById('testdiv');

    var rng = document.createRange();
    rng.setStartBefore(mydiv);
    htmlFrag = rng.createContextualFragment(content);
    while (mydiv.hasChildNodes())
    mydiv.removeChild(mydiv.lastChild);
    mydiv.appendChild(htmlFrag);
    }

    When fillDiv is called from the web page, an alert box pops up as it
    should.

    The problem I'm encountering is when the <script> block uses
    document.write()
    to modify content. Specifically, some of the code I'm encountering is
    from
    Javascript Tree-menu libraries that use document.write() to output
    their menus.

    A minimal implementation example of the problem can be shown by
    replacing the "alert()"
    call above with document.write():


    var content = "<SCRIPT language='javascript' type='text/javascript'>" +
    "\n"
    + 'document.write("<strong>Hello World.</strong>");' + "\n"
    + '</SCRIPT>' + "\n";

    function fillDiv()
    {
    var mydiv = document.getElementById('testdiv');

    var rng = document.createRange();
    rng.setStartBefore(mydiv);
    htmlFrag = rng.createContextualFragment(content);
    while (mydiv.hasChildNodes())
    mydiv.removeChild(mydiv.lastChild);
    mydiv.appendChild(htmlFrag);
    }

    When fillDiv is called from the web page, the page flashes very
    quickly,
    showing "Hello World", but the page content is then immediately
    replaced by
    the original content.

    As I have no control over the <script> blocks, does anyone have any
    suggestions for
    making the document.write() output behave correctly (be written to the
    target DIV)
    when executed within the contextual fragment?

    By the way, I'm testing this on Firefox 1.5.

    Thanks much,

    --Ethan
    , Jun 24, 2006
    #1
    1. Advertising

  2. wrote:



    > var content = "<SCRIPT language='javascript' type='text/javascript'>" +
    > "\n"
    > + 'document.write("<strong>Hello World.</strong>");' + "\n"
    > + '</SCRIPT>' + "\n";
    >
    > function fillDiv()
    > {
    > var mydiv = document.getElementById('testdiv');
    >
    > var rng = document.createRange();
    > rng.setStartBefore(mydiv);
    > htmlFrag = rng.createContextualFragment(content);
    > while (mydiv.hasChildNodes())
    > mydiv.removeChild(mydiv.lastChild);
    > mydiv.appendChild(htmlFrag);
    > }
    >
    > When fillDiv is called from the web page, the page flashes very
    > quickly,
    > showing "Hello World", but the page content is then immediately
    > replaced by
    > the original content.


    How exactly do you call the fillDiv function?

    In general note that createContextualFragment is Mozilla only, besides
    the newly released Opera 9 also featuring it.

    And do not expect any browser to behave the same if you mix W3C DOM Core
    methods like appendChild to insert script with document.write.
    document.write is useful to overwrite the complete document or to use it
    while a document loads. Then the document.write happens where you call it.
    There is however no clear definition as to what has to happen when you
    have document.write in a dynamically inserted script. IE/Win for
    instance only excutes such dynamically inserted script if you use the
    defer attribute which rules out that document.write is used.
    You will need to change your approach.

    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Jun 25, 2006
    #2
    1. Advertising

  3. Guest

    Martin Honnen wrote:
    > wrote:
    >
    >
    >
    > > var content = "<SCRIPT language='javascript' type='text/javascript'>" +
    > > "\n"
    > > + 'document.write("<strong>Hello World.</strong>");' + "\n"
    > > + '</SCRIPT>' + "\n";
    > >
    > > function fillDiv()
    > > {
    > > var mydiv = document.getElementById('testdiv');
    > >
    > > var rng = document.createRange();
    > > rng.setStartBefore(mydiv);
    > > htmlFrag = rng.createContextualFragment(content);
    > > while (mydiv.hasChildNodes())
    > > mydiv.removeChild(mydiv.lastChild);
    > > mydiv.appendChild(htmlFrag);
    > > }
    > >
    > > When fillDiv is called from the web page, the page flashes very
    > > quickly,
    > > showing "Hello World", but the page content is then immediately
    > > replaced by
    > > the original content.

    >
    > How exactly do you call the fillDiv function?
    >
    > In general note that createContextualFragment is Mozilla only, besides
    > the newly released Opera 9 also featuring it.
    >
    > And do not expect any browser to behave the same if you mix W3C DOM Core
    > methods like appendChild to insert script with document.write.
    > document.write is useful to overwrite the complete document or to use it
    > while a document loads. Then the document.write happens where you call it.
    > There is however no clear definition as to what has to happen when you
    > have document.write in a dynamically inserted script. IE/Win for
    > instance only excutes such dynamically inserted script if you use the
    > defer attribute which rules out that document.write is used.
    > You will need to change your approach.
    >
    > --
    >
    > Martin Honnen
    > http://JavaScript.FAQTs.com/


    Hi Martin--

    I agree that trying to get document.write() to work correctly in this
    situation is likely futile, and I will try a different path. To answer
    your first question, fillDiv is executed using the following HTML:

    <a href=# onClick='fillDiv()'>Click to fill</a>
    <div id=testdiv>

    </div>

    Thank you very much for taking the time to respond to my question.

    --Ethan
    , Jun 25, 2006
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. morrell
    Replies:
    1
    Views:
    936
    roy axenov
    Oct 10, 2006
  2. JohnH
    Replies:
    0
    Views:
    231
    JohnH
    May 19, 2004
  3. Torsten Mohr
    Replies:
    0
    Views:
    87
    Torsten Mohr
    Dec 17, 2003
  4. Steve
    Replies:
    1
    Views:
    273
    Richard Cornford
    Apr 9, 2005
  5. Replies:
    0
    Views:
    104
Loading...

Share This Page