Dynamical loading of html files and executing of its javascript content.

Discussion in 'Javascript' started by mowsen@googlemail.com, May 30, 2007.

  1. Guest

    Hello Group,


    i'm using a little "ajax" loader script to dynamically load files into
    different "div" tags on my main site. the code for this part looks
    like:

    function loader() {
    var args = loader.arguments;
    switch (args[0]) { case
    "load_page":
    if (document.getElementById) {
    var x = (window.ActiveXObject) ? new
    ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(); //create
    xmlhttp object
    }
    if (x) {
    x.onreadystatechange = function() {
    if (x.readyState == 4 && x.status == 200) {
    el = document.getElementById(args[2]);
    var viewData = x.responseText;
    splitcode(el, viewData, args[2]);
    }
    }
    x.open(args[3], args[1], true);
    x.send(args[4]);
    }
    break;
    }
    }

    i.e.: i call it through: loader('load_page', 'test/test.html', 'main',
    'GET', 'null');

    now, i want to get the javascript in test.html executed. for this
    purpose i wrote splitcode(), which searches for <script> tags and
    executes them.. this looks like:

    function splitcode(el, viewData, id) {
    var regexp1 = /<script(.|\n)*?>(.|\n|\r\n)*?<\/script>/ig;
    var regexp2 = /<script(.|\n)*?>((.|\n|\r\n)*)?<\/script>/im;
    var regexp3 = /<script src(.|\n)*?>(.|\n|\r\n)*?<\/script>/ig;
    var regexp4 = /src.*\s\b/ig;

    /* draw html first */
    htmlpart = viewData.replace(regexp1, "");
    el.innerHTML = htmlpart;

    var result = viewData.match(regexp3);

    if (result) {
    for (var i = 0; i < result.length; i++) {
    var srcScript = result.match(regexp4);
    srcScript += "";
    srcScript = srcScript.substr(5, srcScript.length-7);
    var scriptContainer = document.createElement('SCRIPT');
    var scriptContainerSrc = document.createAttribute('src');
    var scriptContainerType = document.createAttribute('type');

    scriptContainerSrc.value = srcScript;
    scriptContainerType.value = "text/javascript";
    scriptContainer.setAttributeNode(scriptContainerSrc);
    scriptContainer.setAttributeNode(scriptContainerType);

    document.getElementsByTagName("head")
    [0].appendChild(scriptContainer);
    }
    }


    var result = viewData.match(regexp1);

    if (result) {
    for (var i = 0; i < result.length; i++) {
    var realScript = result.match(regexp2);
    executeScript(realScript[2]);
    }
    }
    }


    function executeScript(scriptFrag) {
    var scriptContainer = document.createElement('SCRIPT');
    document.getElementsByTagName("head")
    [0].appendChild(scriptContainer);
    scriptContainer.text = scriptFrag;
    }


    This all works quite well within firefox. But for IE and Safari it
    won't do at all! IE at least, lets me execute a function noted in
    test.html once, but then it seems as if it has lost the javascript
    code or can't find it again...

    Any ideas to overcome this are greatly appreciated!

    Moka Toka
     
    , May 30, 2007
    #1
    1. Advertising

  2. RobG Guest

    On May 31, 10:22 am, Randy Webb <> wrote:
    [...]
    > <FAQ***RY>
    >
    > How do I execute scripts retrieved via AJAX?
    > </FAQ***RY>
    > That is there as a marker for myself and for comments from anyone who
    > has any thoughts/comments on the question.


    Great idea. Since you suggested it, I'll give you the standard FAQ
    maintainer response: post your best effort for criticism and see what
    eventuates. ;-)


    --
    Rob
     
    RobG, May 31, 2007
    #2
    1. Advertising

  3. dd Guest

    On May 30, 3:43 pm, wrote:
    > function executeScript(scriptFrag) {
    > var scriptContainer = document.createElement('SCRIPT');
    > document.getElementsByTagName("head")
    > [0].appendChild(scriptContainer);
    > scriptContainer.text = scriptFrag;
    > }


    You should be setting the .text attribute of the scriptContainer
    before it gets appended to the head.
     
    dd, May 31, 2007
    #3
  4. Guest

    Hey, i already responded but it doesn't show up.... so i just post it
    again:

    that's what i use now:

    function executeScript(scriptFrag) {

    var scriptContainer = document.createElement('SCRIPT');

    if(document.createTextNode("test")) {
    var s = document.createTextNode(scriptFrag);
    scriptContainer.appendChild(s);
    document.getElementsByTagName("head")
    [0].appendChild(scriptContainer);
    } else {
    document.getElementsByTagName("head")
    [0].appendChild(scriptContainer);
    scriptContainer.text = scriptFrag;
    }
    }

    This at least works for Safari and Firefox on my Mac. IE seems to hang
    on the regexp, it returns "null" where there should be the <script>
    tag..

    >> var regexp3 = /<script src(.|\n)*?>(.|\n|\r\n)*?<\/script>/ig;


    > Right here, rather than search the way you are, grab the script nodes of
    > the el element. Then it won't matter whether it has a source attribute
    > or inline scripts, you have the blocks. Then check them for src
    > attributes and code accordingly.


    So Randy, could you explain to me howto grap them your way?


    Thanks,
    Moka
     
    , May 31, 2007
    #4
  5. Guest

    so well, it's me again :) i think i got what you mean. splitcode now
    looks like:

    function splitcode(el, viewData, id) {

    el.innerHTML = viewData;

    var scriptNodes = el.getElementsByTagName('script');

    var scriptCount = scriptNodes.length;




    for (var i = 0; i < scriptCount; i++) {

    var scriptFile = false;
    var scriptNode = scriptNodes;

    for (var j=0; j < scriptNode.attributes.length; j++) {
    if (scriptNode.attributes[j].nodeName == "src")
    scriptFile = true;
    }

    if (scriptFile) {
    var scriptContainer = document.createElement('SCRIPT');
    var scriptContainerSrc = document.createAttribute('src');
    var scriptContainerType = document.createAttribute('type');

    scriptContainerSrc.value =
    scriptNode.attributes['src'].nodeValue;
    scriptContainerType.value =
    scriptNode.attributes['type'].nodeValue;

    scriptContainer.setAttributeNode(scriptContainerSrc);
    scriptContainer.setAttributeNode(scriptContainerType);

    document.getElementsByTagName("head")
    [0].appendChild(scriptContainer);
    }
    else {
    var scriptContainer = document.createElement('SCRIPT');
    var scriptFrag = scriptNode.firstChild.nodeValue;

    if(document.createTextNode("test")) {
    var s = document.createTextNode(scriptFrag);
    scriptContainer.appendChild(s);
    document.getElementsByTagName("head")
    [0].appendChild(scriptContainer);
    } else {
    document.getElementsByTagName("head")
    [0].appendChild(scriptContainer);
    scriptContainer.text = scriptFrag;
    }
    }
    }
    }


    and, guess what?! safari returns 0 for scriptNodes.length; (should be
    2, FF works well).

    frustrated,
    moka
     
    , May 31, 2007
    #5
  6. RobG Guest

    On May 31, 10:20 pm, wrote:
    > so well, it's me again :) i think i got what you mean. splitcode now
    > looks like:
    >
    > function splitcode(el, viewData, id) {
    >
    > el.innerHTML = viewData;
    >
    > var scriptNodes = el.getElementsByTagName('script');


    innerHTML has quirks in various browsers. If you are adding HTML to a
    page using innerHTML (often as a response to an XMLHttpRequest) that
    includes script elements, the most common method is to strip out the
    script elements first, add the HTML and then:

    - For script elements that contain text (i.e. code) use eval to run
    it
    - For script elements have a viable scr attribute value, use that to
    add the script

    The trick with eval is that it changes the scope of the eval'd
    scripts, but that can be dealt with. The issue with stripping out the
    script elements means they run after all the HTML has been added, so
    if you expect them to to run as the HTML goes in you may have a
    problem.

    The topic has been covered here before at length:

    <URL:
    http://groups.google.com.au/group/c...q=eval scripts&rnum=17&hl=en#221557c29ed3dfde
    >


    There are many useful links in that thread.


    --
    Rob
     
    RobG, Jun 1, 2007
    #6
  7. Guest

    > > el.innerHTML = viewData;

    >
    > innerHTML has quirks in various browsers. If you are adding HTML to a
    > page using innerHTML (often as a response to an XMLHttpRequest) that
    > includes script elements, the most common method is to strip out the
    > script elements first, add the HTML



    and how do you add the HTML, if not with .innerHTML?


    > and then:
    >
    > - For script elements that contain text (i.e. code) use eval to run
    > it



    i've read through eval sometimes, and the most common opinion was:
    eval = evil!
    dunno really why though, could you explain the disadvantage of using
    it?
    .... and how would you strip the <script> tags out? with regexp in my
    first post?
    or loading the whole thing into a div, strip and save them out, and re-
    put them into again?


    thanks alot,
    moka
     
    , Jun 1, 2007
    #7
  8. Guest

    i forgot to append: the javascript should be available all the time
    after loading the page. there are functions which get called more than
    once on loading. as i understand the eval function, my js code only
    gets executed once, while my loader evals it. but not, if i click on
    the loaded pages' button which should execute it too?!

    any suggestions?

    moka
     
    , Jun 1, 2007
    #8
  9. Evertjan. Guest

    Randy Webb wrote on 02 jun 2007 in comp.lang.javascript:
    > It doesn't directly answer your question, but, the main problem is that
    > you are trying to insert code/content into another page that was never
    > intended to be inserted that way. For an "AJAX site" to be efficient and
    > actually capitalize on the speed gains then the backend *must* be set up
    > to generate content that is optimized for the front end.


    I totally agree with you, Randy.

    The fact remains
    that AJAX as such is a typical example of using the web
    and clientside javascript as it was not intended.

    ;-)

    The nice thing about programming in general
    is it's flexability to do things that where not intended
    by the programmers.


    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
     
    Evertjan., Jun 2, 2007
    #9
  10. Evertjan. Guest

    Randy Webb wrote on 03 jun 2007 in comp.lang.javascript:

    > Evertjan. said the following on 6/2/2007 11:35 AM:
    >> Randy Webb wrote on 02 jun 2007 in comp.lang.javascript:
    >>> It doesn't directly answer your question, but, the main problem is
    >>> that you are trying to insert code/content into another page that
    >>> was never intended to be inserted that way. For an "AJAX site" to be
    >>> efficient and actually capitalize on the speed gains then the
    >>> backend *must* be set up to generate content that is optimized for
    >>> the front end.

    >>
    >> I totally agree with you, Randy.
    >>
    >> The fact remains
    >> that AJAX as such is a typical example of using the web
    >> and clientside javascript as it was not intended.

    >
    > Using it for anything other than secondary features, or, are you
    > referring to using javascript to load complete documents to insert
    > into a container? If the first, then I disagree with you as javascript
    > may have started out as an option for additional features but it has
    > almost become a de facto necessity for it to be enabled for most of
    > the web. It is moving closer and closer to mandatory and not the other
    > way around.


    I think AJAX or something like it should become mainstream to clientside
    javascript by having a set of simple commands that can be cross browser
    compatible.

    In the main time the using of javascript engine external xmlhttp-like
    functions is a necessity, BECAUSE such in-page client/server
    communication was never forseen at the present javascript implementation
    stages.

    A multitasking ability of these in-page client/server communication
    capable browsers will become a necessity, since the "pointless" waiting
    for a single AJAX communication to complete [or abort] even[?] breaks up
    Googles complex interactivity efforts.


    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
     
    Evertjan., Jun 3, 2007
    #10
    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. Jacob Kroon

    Dynamical loading of modules

    Jacob Kroon, Oct 3, 2005, in forum: Python
    Replies:
    0
    Views:
    261
    Jacob Kroon
    Oct 3, 2005
  2. benny
    Replies:
    0
    Views:
    258
    benny
    Jan 11, 2007
  3. haiwen
    Replies:
    5
    Views:
    126
    haiwen
    Oct 27, 2003
  4. thunk
    Replies:
    1
    Views:
    323
    thunk
    Mar 30, 2010
  5. thunk
    Replies:
    0
    Views:
    496
    thunk
    Apr 1, 2010
Loading...

Share This Page