By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,017 Members | 1,158 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,017 IT Pros & Developers. It's quick & easy.

Dynamic JavaScript Loading (xmlhttprequest)

RMWChaos
100+
P: 137
Currently testing in: WinVista / IE7

I have been working on getting xmlhttprequest going for weeks now. I have finally gotten a semi-working script going. Pulling up text or xml files works great and populates into the webpage; however, executing javascript has a few problems:

1. Opens on a blank page, but not a new page. It appears to compeltely overwrite the original page. I want it to update the existing page by loading within a <div> element.

2. I cannot seem to get functions to work. It seems as if the script is not opening in the global space despite using the 'window' element.

3. What format should the external javascript file that I am attempting to load be in? I think that I have figured out not to include the '<!--' and '//-->' tags normally included in an external javascript file.

4. I have no idea how to tell when the browser is using JScript or JavaScript (friggin' Microsoft :-D) and how the two may respond differently.

I have been reading a lot on the global issues, but none of the suggested fixes has worked for me. One thing that I've learned is that in IE7, all three of these methods of initiating an external javascript file work: eval(), execScript(), and setTimeout().

Here is the code for your viewing pleasure (I break my code out for ease of reading; so I apologize if it seems longer than normal):

Expand|Select|Wrap|Line Numbers
  1.  
  2. <!--
  3.  
  4. var xmlhttp;
  5.  
  6. var fileType;
  7.  
  8. function loadData(url)
  9.  
  10.     {
  11.  
  12.     xmlhttp = null;
  13.  
  14.     fileType = url;
  15.  
  16.     // code for native xmlhttp
  17.  
  18.     if (window.XMLHttpRequest)
  19.  
  20.         {
  21.  
  22.         xmlhttp = new XMLHttpRequest();
  23.  
  24.         }
  25.  
  26.     // code for old IE
  27.  
  28.     else if (window.ActiveXObject)
  29.  
  30.         {
  31.  
  32.         xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  33.  
  34.         }
  35.  
  36.     if (xmlhttp != null)
  37.  
  38.         {
  39.  
  40.         xmlhttp.open("GET", url, false);
  41.  
  42.         xmlhttp.onreadystatechange = processData;
  43.  
  44.         xmlhttp.send(null);
  45.  
  46.         }
  47.  
  48.     else
  49.  
  50.         {
  51.  
  52.         alert("Please upgrade to a browser that supports XMLHTTP.");
  53.  
  54.         }
  55.  
  56.     }
  57.  
  58. function processData()
  59.  
  60.     {
  61.  
  62.     // if xmlhttp shows "loaded"
  63.  
  64.     if (xmlhttp.readyState == 4)
  65.  
  66.         {
  67.  
  68.         // if "OK"
  69.  
  70.         if (xmlhttp.status == 200)
  71.  
  72.             {
  73.  
  74.             // if text document
  75.  
  76.             if (fileType.lastIndexOf("txt") != -1)
  77.  
  78.                 {
  79.  
  80.                 document.getElementById('content').innerHTML = xmlhttp.responseText;
  81.  
  82.                 }
  83.  
  84.             // if xml document
  85.  
  86.             if (fileType.lastIndexOf("xml") != -1)
  87.  
  88.                 {
  89.  
  90.                 // xml parse code here for xmlhttp.responseXML
  91.  
  92.                 }
  93.  
  94.             // if javascript file
  95.  
  96.             if (fileType.lastIndexOf("js") != -1)
  97.  
  98.                 {
  99.  
  100.                 // if MSIE
  101.  
  102.                 if (window.execScript)
  103.  
  104.                     {
  105.  
  106.                     window.execScript(xmlhttp.responseText, "javascript");
  107.  
  108.                     return null;
  109.  
  110.                     }
  111.  
  112.                 // if others
  113.  
  114.                 else if (window.eval)
  115.  
  116.                     {
  117.  
  118.                     window.eval(xmlhttp.responseText);
  119.  
  120.                     }
  121.  
  122.                 // if Safari
  123.  
  124.                 else
  125.  
  126.                     {
  127.  
  128.                     window.setTimeout(xmlhttp.responseText, 0);
  129.  
  130.                     }
  131.  
  132.                 }
  133.  
  134.             }
  135.  
  136.         else
  137.  
  138.             {
  139.  
  140.             alert("Problem retrieving data:\n" + xmlhttp.status + "\n" + xmlhttp.statusText);
  141.  
  142.             }
  143.  
  144.         }
  145.  
  146.     }
  147.  
  148. //-->
  149.  
  150.  
Thanks in advance for your help.
Oct 19 '07 #1
Share this Question
Share on Google+
20 Replies


RMWChaos
100+
P: 137
By the way, this:

Expand|Select|Wrap|Line Numbers
  1. document.getElementById('content').innerHTML = window.execScript(xmlhttp.responseText, "javascript");
throws a "Permission Denied" error but otherwise operates exactly the same.

In all cases where loading an external javascript file, the "Back" button functions; so it is not loading within the original page as it should. This does not occur with either Text or XML files.

Oh, I even tried renaming my javascript files to .txt and adding <script> and </script> to them, which sort of worked. At least they loaded within the original page; however, the functions they called within the external script file still did not work. So once again, the global scope problem. Grrr.

What am I doing wrong!?
Oct 19 '07 #2

gits
Expert Mod 5K+
P: 5,371
hi ...

may be you could try something like this:

the js-text should look like the assignment to responseText:

Expand|Select|Wrap|Line Numbers
  1. var responseText = 'window.test = function test(x) { alert(x); }; test(3);';
  2.  
  3. eval(responseText);
  4.  
  5. // you also may do now:
  6. test(4):
  7.  
kind regards
Oct 19 '07 #3

RMWChaos
100+
P: 137
Thanks for the reply, gits. If I understand your example code correctly, you are suggesting creating a global var and setting it equal to some function. I assume you mean the function would be the responseText from xmlhttprequest. I have tried that. Basically I did this:

Expand|Select|Wrap|Line Numbers
  1. var response; // along with the other global vars such as xmlhttp
  2.  
  3. // in the processData() function
  4.  
  5. response=xmlhttp.responseText;
  6.  
  7. execScript(response);
  8. // or
  9. window.execScript(response);
  10. //same for eval() or setTimeout()
  11.  
In all cases, the result was the same. I even tried setting a global variable for 'window', which probably makes no sense, and that didn't work either.

I have got to be doing something silly here to be causing the problem.

Thanks again.
Oct 19 '07 #4

gits
Expert Mod 5K+
P: 5,371
could you please post an example responseText that you are trying to eval?
Oct 19 '07 #5

RMWChaos
100+
P: 137
Oh wait! Are you saying to do this:

Expand|Select|Wrap|Line Numbers
  1. var loadData= function() { // here I would place my loadData() code};
  2.  
  3. // then call loadData from the processData() function
  4.  
  5. function processData() {
  6.  
  7. // ...
  8.  
  9. window.execScript(loadData, "javascript);
  10.  
  11. }
  12. // then I would have to change the way I initiate the script and pass 'url' to loadData
  13.  
Am I on the right track? I will try this now.
Oct 19 '07 #6

RMWChaos
100+
P: 137
Below is some example responseText from an external javascript file called loadLogin.js. So from my webpage, I might have a button "Login" with an onclick property:

[HTML]onclick="loadData('loadLogin.js')"[/HTML]

Expand|Select|Wrap|Line Numbers
  1.  
  2. function loginOver()
  3.  
  4.     {
  5.  
  6.     document.login.src = "../images/loginHover.jpg";
  7.  
  8.     }
  9.  
  10. function loginOut()
  11.  
  12.     {
  13.  
  14.     document.login.src = "../images/loginDefault.jpg";
  15.  
  16.     }
  17.  
  18. function submitOver()
  19.  
  20.     {
  21.  
  22.     document.submit.src = "../images/submitHover.jpg";
  23.  
  24.     }
  25.  
  26. function submitOut()
  27.  
  28.     {
  29.  
  30.     document.submit.src = "../images/submitDefault.jpg";
  31.  
  32.     }
  33.  
  34. function loginForm()
  35.  
  36.     {
  37.  
  38.     document.write('<form name="login" action="http://api.eve-online.com/account/Characters.xml.aspx" method="post">');
  39.  
  40.         document.write('UserID: <input type="text" name="userID" size="10" /><br /><br />');
  41.  
  42.         document.write('APIKey: <input type="text" name="apiKey" size="75" /><br /><br />');
  43.  
  44.         document.write('<input type="image" alt="Submit" name="submit" value="Submit" src="../images/submitDefault.jpg" onmouseover="submitOver" onmouseout="submitOut" />');
  45.  
  46.     document.write('</form>');
  47.  
  48.     }
  49.  
  50. document.write('<img src="../images/loginDefault.jpg" name="login" alt="Login" onmouseover="loginOver" onmouseout="loginOut" onclick="loginForm" />');
  51.  
  52.  
Oct 19 '07 #7

RMWChaos
100+
P: 137
Ok, so calling var loadData from function processData() does not make sense because processData is waiting on the new XMLHttpRequest to be readystate ==4 and status==200.

There has got to be some way to get the functions from an external javascript file pulled in from xmlhttprequest loaded into global scope. I thought this happened automatically with execScript() and setTimeout().

Perhaps because my xmlhttprequest script is an external file itself, not embedded in the HTML code, window refers back to the script file and not the htm file. Does that make sense? I am going to try putting the code directly into my webpage and see what happens.
Oct 19 '07 #8

RMWChaos
100+
P: 137
Nope. Exact same issue occurs when I run the xmlhttprequest script directly from within the html code. So this has something to do with how execScript() is evaluating the code. It is not loading the functions in the global scope or not remembering them or something.
Oct 19 '07 #9

gits
Expert Mod 5K+
P: 5,371
hi ...

did you try something that i showed you in my first post (#3)? ... as far as i can see that should work, i tested that with firefox ... in your processData() function you first should eval the responseText. after that you should be able to call the function by name only? do you get any errors? or do you just have no access to the evaluated functions?

kind regards
Oct 20 '07 #10

gits
Expert Mod 5K+
P: 5,371
and try to avoid document.write ... this destroys your current document, you may use regular dom-methods (createElement(), appendChild() etc.) for that ... or use innerHTML ...

kind regards
Oct 20 '07 #11

RMWChaos
100+
P: 137
gits,

I don't completely understand what you are suggesting I do in your post #3. Sorry, I have only been doing javascripting for about a month now; so without explicit examples, I sometimes get lost.

To answer your other question, once the external javascript file is either eval'd, execScript'd, or setTimeout'd, it does not appear that I can call any of the functions from the file. I will try a few things to confirm.

The example I gave was just one of the shorter external javascripts I am using, and I certainly will remove the document.write in favor of the dom method as you suggest. Other scripts I am calling do not have document.write in them and run into the same problem.

Figures I choose some of the most complex type of coding for my first project.

Thanks for your help! :-)
Oct 20 '07 #12

gits
Expert Mod 5K+
P: 5,371
first try the alert example i gave you ... and tell if that works ... please!

put the test-function to one of your js files. use firefox to test it. before that ... install the firebug extension so that we may easily debug our code ... i strongly recommend that step. ... next: load our test function, eval it and try to call it after the eval ... and then ... please post back the results ...

kind regards
Oct 20 '07 #13

RMWChaos
100+
P: 137
gits,

Added your code in post #3 to my loadXHR.js file in place of my other data processing files in processData(). Worked fine in both IE and FireFox. Firebug did not report any errors. An alert popped up with "3" in both IE and FF as expected.

I am going to test further with my original code using Firebug to see what errors it logs. I strongly suspect this has something to do with loading the external javascript in the global scope.

Thanks.
Oct 21 '07 #14

gits
Expert Mod 5K+
P: 5,371
hi ...

but when the test() - alert worked ... it is loaded in the gobal scope when you could call it by name and with a new param = 4 after the eval. so in that case your code should work too ... tell what firebug says ...

kind regards
Oct 21 '07 #15

RMWChaos
100+
P: 137
gits,

Okay, I tested as you said. I used a loadTest.js script with the code "return;" in it, and nothing else.

First, I click my button with attribute onclick="loadData('loadTest.js')" and it returns alert 3.

Next, I click another button with attribute onclick="test(4)" and it returns alert 4.

Firebug shows both functions returning "return;" as expected.

So it is loading into the global scope here.
Oct 21 '07 #16

gits
Expert Mod 5K+
P: 5,371
so ... now we know how to do it ... :) now try your functions to load ... and tell what firebug says ... please, and don't try to have a document.write there ... at the moment ... we may try to replace that later on ...

kind regards
Oct 21 '07 #17

RMWChaos
100+
P: 137
@#%$#@!!! Argh!

gits,

Okay, my original code is working now in IE and FF without any changes, but not NN for some reason. The problem, as it turns out, is that xmlhttprequest and document.write do not play well together. By themselves, each works fine, but following your advice, I will be dropping document.write from my code altogether.

As for NN, is there something different about how it interprets <img> attributes? Not even the alt="" text shows up when I hover, and the onclick="" is not launching.

Thanks again for all your help!!!
Oct 21 '07 #18

gits
Expert Mod 5K+
P: 5,371
hi ...

in any case you should always avoid document.write ... use innerHTML instead ... as the simple and beginner solution :) ... the best way owuld be to create regular nodes and append them through dom-handling ...

in case you could or have to isolate a NN specific problem ... after changing the handling ... you should start a new thread in the forum regarding this ...

as far as i can see ... it works now ... but you have to replace the document.writes?

kind regards
Oct 21 '07 #19

RMWChaos
100+
P: 137
gits,

That's correct, it works now. I am working on using dom-handling to create and remove nodes and plan on converting my text files to xml files, but it's taking a bit of trial and error. innerHTML will have to work for the time being. ;-)

I will open a new thread on the NN issue.

Take care and thanks for all your help!
Oct 21 '07 #20

gits
Expert Mod 5K+
P: 5,371
hi ...

glad to hear that you are on track at least :) ...

kind regards
Oct 21 '07 #21

Post your reply

Sign in to post your reply or Sign up for a free account.