Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: DOM Reload?

  1. #1
    Join Date
    Jul 2010
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default DOM Reload?

    I've got an issue that really has me stumped. Rather than post my long convoluted code, I've put 2 test pages together that really illustrate my problem. They're as short as possible while still being able to duplicate the issue. I've posted these files on one of my servers, so you can see the issue live.

    File 1: http://www.vampirerave.com/rave_wars/test/test1.php
    File 2: http://www.vampirerave.com/rave_wars/test/test2.php

    File 1 pulls data from file 2 via Ajax at 3 second intervals. However, it's only 'half working'.

    Here's the code:

    File 1:
    Code:
    <html>
    <head>
    <script type="text/javascript">
      function testFunction(){
        var http;
        var url = "http://www.vampirerave.com/rave_wars/test/test2.php"; 
        try  { http = new XMLHttpRequest(); }
        catch (e) {
          try { http = new ActiveXObject("Msxml2.XMLHTTP"); }
          catch (e) {
            try { http = new ActiveXObject("Microsoft.XMLHTTP"); }
            catch (e) {
              alert("Please update your browser.");
              return false;
            }
          }
        }
        http.open("GET", url, true);
        http.onreadystatechange = function() {
          if(http.readyState == 4 && http.status == 200) {
            document.getElementById('myDiv').innerHTML+=http.responseText;
          }
        }
        http.send(null);  
        http.close;	    
        setTimeout("testFunction()",3000);
      }
      window.onload=function(){
        testFunction();
      }   
    </script>
    </head>
    <body>
    <div id="myDiv">
    Starting...<br /><br />
    </div>
    <body>
    </html>
    File 2:
    Code:
    Hello World!<br /><br />
    <script type="text/javascript">
    var myDate = new Date();
    document.write('The date is: ' + myDate + '<br /><br />');
    </script>
    As you can see, Hello World is being pulled and displayed just fine. However, the javascript doesn't execute. If you load file 2 directly, the javascript executes just fine and displays the date.

    Firebug isn't throwing any errors with either page. I'm guessing this has something to do with the DOM, but I have no idea how to fix it. The issue persists across all browsers, so I know it's not a browser-related issue.

    Any help is greatly appreciated as I have been struggling with this all day.

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Scripts on AJAX imported pages generally do not execute.

    The thing is, if you imported that page and its script ran, that document.write() bit would overwrite the existing page. The script cannot run until it's imported because javascript cannot run without the browser, and the browser cannot 'see' the page until its content is loaded into (in this case) file 1.

    You could use PHP to get the date:

    File 2:
    PHP Code:
    Hello World!<br /><br />
    <?php
    echo 'The date is: ' date("D M d Y H:i:s \G\M\TO (T)");
    ?>
    But this will be the server time, not the user's time as would be the case with javascript. The above would output something like so:

    Hello World!

    The date is: Sun Jul 04 2010 07:10:28 GMT+0000 (UTC)
    My server is UTC, yours may be as well, either that or the timezone of its locale, or the locale it mostly services, or wants to look like it services.

    You could use javascript as part of the onreadystatechange function to insert the date into the fetched content.

    Or you could investigate a library like jQuery where scripts can be fetched. This would be different than what you are doing, but a script could be fetched to place the javascript date somewhere on the page.

    MooTools has an interesting option with its AJAX function:

    http://mootools.net/docs/core/Request/Request

    evalResponse - (boolean: defaults to false) If set to true, the entire response will be evaluated. Responses with javascript content-type will be evaluated automatically.
    I'm not sure what this does. Even if it executes the script, it will not get you what you want either (because of the document.write() bit). Perhaps with a different script.
    Last edited by jscheuer1; 07-04-2010 at 07:41 AM. Reason: precision
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. #3
    Join Date
    Jul 2010
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Well, the date thing and the contents of file 2 was just a simple way to illustrate the issue. In my actual application 'file 2' is a DHTML menu that dynamically changes based on certain events. It's an Ajax/Comet setup, and I can't get the DHTML to work when it's refreshed. It works fine on first load, but not on subsequent reloads.

    I don't think there's a PHP solution here because it's a dynamic DHTML menu that I'm trying to import. This is also a project in development, and there are other issues like this on the horizon (so I'm trying to get ahead of it now). The project it Ajax/Comet/javascript heavy.

    I've never worked with jQuery or mootools, but I'll look into them and see if either might solve the problem.

    Thanks for your suggestions.

  4. #4
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Your best bet might be combining PHP and javascript. PHP will execute as the server is fetching the content, javascript generally will not execute, but you can invoke javascript as part of your onreadystatechange function, something like:

    Code:
        http.onreadystatechange = function() {
          if(http.readyState == 4 && http.status == 200) {
            document.getElementById('myDiv').innerHTML+=http.responseText;
            //javascript to run against the newly imported content can go here.
          }
        }
    Also, with jQuery you can set up events 'live'. That way they will fire on imported content, even though they are set before the content arrives.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  5. #5
    Join Date
    Sep 2007
    Location
    The Netherlands
    Posts
    1,881
    Thanks
    49
    Thanked 266 Times in 258 Posts
    Blog Entries
    56

    Default

    You can force scripts on AJAX imported pages to execute by document.writing the external pages containing the scripts into a hidden div. Demo (I used html-files, but I guess this will work with php-files as well):
    test1.html:
    Code:
    <head>
    <script type="text/javascript">
    var pageRequest = false 
    /*@cc_on 
    @if (@_jscript_version >= 5)
    try {
    pageRequest = new ActiveXObject("Msxml2.XMLHTTP")
    }
    catch (e){
    try {
    pageRequest = new ActiveXObject("Microsoft.XMLHTTP")
    }
    catch (e2){
    pageRequest = false
    }
    }
    @end
    @*/
    
    if (!pageRequest && typeof XMLHttpRequest != 'undefined')
    pageRequest = new XMLHttpRequest()
    
    function include(content,id){
    var newdiv = document.createElement("div");
    newdiv.innerHTML = content;
    document.getElementById(id).appendChild(newdiv); 
    }
    
    if (pageRequest){
    pageRequest.open('GET', 'test2.html', false)
    pageRequest.send(null); ajax_include1=pageRequest.responseText;
    
    document.write('<div style="display:none">');
    document.write(ajax_include1);
    document.write('<\/div>');
    }
    </script>
    </head>
    
    <body >
    
    <div>
    What you see above the horizontal line is content from <i>test1.html.</i><br><br>
    Click on the link to add dynamic content (the date) from external <i>test2.html</i> to area below &rarr; <a href="javascript: void(0)" onclick=load_date()>what's the date?</a><br><br>
    Click <a href="javascript: void(0)" onclick="document.getElementById('external').innerHTML=''; document.getElementById('external').style.background='white'">here</a> to empty the area below.
    </div><hr>
    
    <div id="external"></div>
    
    </body>
    test2.html:
    Code:
    <script type="text/javascript">
    function load_date(){
    var myDate = new Date();
    document.getElementById('external').innerHTML+='Hello World! The date is: ' + myDate+'<br><br>';
    document.getElementById('external').style.background='red';
    document.getElementById('external').style.color='white';
    }
    </script>
    If the imported external js is complicated, you should make it external with respect to the file to which it belongs (IE precaution).
    ===
    Arie Molendijk.
    Last edited by molendijk; 07-04-2010 at 05:26 PM. Reason: Correction

  6. #6
    Join Date
    Jul 2010
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Quote Originally Posted by jscheuer1 View Post
    Your best bet might be combining PHP and javascript. PHP will execute as the server is fetching the content, javascript generally will not execute, but you can invoke javascript as part of your onreadystatechange function,
    Unfortunately this won't work, as I am dynamically generating the javascript code in my actual project. That's why it's being fetched on a seperate page via AJAX. The javascript must be contained in file 2.

    Think items being added and removed in real time from a list. Each item in the list has it's own DHTML menu, so the javascript needs to change/update with each refresh.

    Quote Originally Posted by molendijk View Post
    You can force scripts on AJAX imported pages to execute by document.writing the external pages containing the scripts into a hidden div.
    I had thought about this, as some AJAX/COMET methods utilize hidden divs or hidden iframes.

    I'm about ready to start working on this again today. I've got 3 good routes to try (jQuery, mootools, hidden div). I'll let you know how it turns out. Thanks for all your help.

  7. #7
    Join Date
    Sep 2007
    Location
    The Netherlands
    Posts
    1,881
    Thanks
    49
    Thanked 266 Times in 258 Posts
    Blog Entries
    56

    Default

    Quote Originally Posted by Beagle72 View Post
    I'm about ready to start working on this again today. I've got 3 good routes to try (jQuery, mootools, hidden div). I'll let you know how it turns out.
    In the meantime I'll correct some errors in my previous post, which was written too hastily.
    test1.html:
    Code:
    <head>
    <script type="text/javascript">
    var pageRequest = false 
    /*@cc_on 
    @if (@_jscript_version >= 5)
    try {
    pageRequest = new ActiveXObject("Msxml2.XMLHTTP")
    }
    catch (e){
    try {
    pageRequest = new ActiveXObject("Microsoft.XMLHTTP")
    }
    catch (e2){
    pageRequest = false
    }
    }
    @end
    @*/
    
    if (!pageRequest && typeof XMLHttpRequest != 'undefined')
    pageRequest = new XMLHttpRequest()
    
    function include(content,id){
    var newdiv = document.createElement("div");
    newdiv.innerHTML = content;
    document.getElementById(id).appendChild(newdiv); 
    }
    
    if (pageRequest){
    pageRequest.open('GET', 'test2.html', false)
    pageRequest.send(null); ajax_include=pageRequest.responseText;
    
    document.write('<div style="display:none">');
    document.write(ajax_include);
    document.write('<\/div>');
    }
    </script>
    </head>
    
    <body >
    
    <div>
    What you see above the horizontal line is content from <i>test1.html.</i>. What you see below the horizontal line is content from <i>test2.html.</i> <br><br>
    Click <a href="javascript: void(0)" onclick="document.getElementById('div1').innerHTML=''; document.getElementById('div1').style.background='white';document.getElementById('div2').innerHTML=''; document.getElementById('div2').style.background='white'">here</a> to empty the area below the horizontal line.<br><br>
    
    <a href="javascript: void(0)" onclick="load_date()">Execute code from test2.html by directly referencing (in test1.html) a function (=load_date()) that is inside test2.html</a><br>
    
    <a href="javascript: void(0)" onclick="include(ajax_include,'div1')">Import text and code from test2.html with the help of a function (=include(content,id)) that is inside test1.html</a>
    </div><hr>
    
    <div id="div1"></div><br>
    <div id="div2"></div>
    
    </body>
    test2.html:
    Code:
    <head>
    <script type="text/javascript">
    function load_date(){
    var myDate = new Date();
    document.getElementById('div2').innerHTML+='Hello World! The date is: ' + myDate+'<br><br>';
    document.getElementById('div2').style.background='red';
    document.getElementById('div2').style.color='white';
    }
    </script>
    </head>
    
    <body>
    <a href="javascript: void(0)" onclick="load_date()">This link is imported from test2.html. It loads the date using function load_date() (in test2.html)</a>
    </body>
    Arie.

  8. #8
    Join Date
    Jul 2010
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Arie,

    Thanks a lot for your assistance. I managed to get it working thanks to your examples

  9. #9
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Arie,

    That's not AJAX (Asynchronous JavaScript and XML), it's a synchronous request and can cause the page to hang.

    Beagle72,

    You say your external page is created dynamically, how?
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  10. #10
    Join Date
    Jul 2010
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Well, in my application it's COMET.

    You're sitting on a page with a COMET channel open. An event is triggered, and a message is sent on the COMET channel telling your browser to reload some data. That data is fetched from file 2 (with code similar to what I posted in my original example for file 1). A div on file 1 that contains the data is replaced (reloaded).

    What I was having problems with, was when the data included javascript on page 2, that javascript wasn't triggering. I put together the above example to illustrate the issue.

    My real file 2 is a list of usernames, each one of which spawns a dhtml window when clicked on. The dhtml windows weren't activating (the javascript was the problem).

    But it's all working now.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •