Javascript includes – yet another way of RPC-ing

July 20th, 2005. Tagged: JavaScript

Javascript files can be included and executed on the fly -- either when loading the page or in run-time. This means that HTTP requests are made without the use of XMLHttpRequest or iframes. This post provides a trail of my experiments with the inclusion of external javascript files.

The problem

I was wondering how feasible it is to call Javascripts only when you need them. Basically not to have a load of <script src="js.js">s at the top of the page, but only those that are actually needed, when they are needed. Also I wanted to figure out an elegant solution whereby you call only one JS and leave it to that script to include more scripts if needed.

First reflex

My first instinct was to try something with document.write and it worked just OK. I created two JS files 1.js and 2.js, then wrote a small function to document.write a script tag and, finally, called this function randomly so that one of the script files is executed randomly.

1.js and 2.js are very simple, each of them contains just an alert().

The function to include a script looks like this:

function include(script_filename) {
    document.write('<' + 'script');
    document.write(' language="javascript"');
    document.write(' type="text/javascript"');
    document.write(' src="' + script_filename + '">');
    document.write('</' + 'script' + '>');
}

Then the random include looks like:

var which_script = Math.floor(Math.random() * 2) + 1 + '.js';

include(which_script);

Here's the test in action.

Now do it 10 times

I wanted to test if I can do the above several times per page and also if I can include and execute for a second time a script that was already executed. Well, it is possible, here's the test. It loops ten times, randomly including 1.js and 2.js

The DOM way

Well, document.write() is not a preferred method for altering an HTML page. Since the page is an XML tree to begin with, we should be using the DOM methods to include a javascript on the fly. But will it work? Yes, it turns out. Here's what I tried:

function include_dom(script_filename) {
    var html_doc = document.getElementsByTagName('head').item(0);
    var js = document.createElement('script');
    js.setAttribute('language', 'javascript');
    js.setAttribute('type', 'text/javascript');
    js.setAttribute('src', script_filename);
    html_doc.appendChild(js);
    return false;
}

This basically creates a new element - a <script> and appends it as a child to the <head> node. Then again the script comes up with a random number - 1 or 2 and calls the function include_dom() as the page loads:

var which_script = Math.floor(Math.random() * 2) + 1 + '.js';

include_dom(which_script);

This worked just beautifully (test 3). Note that in Firefox and IE you can get around without actually having a <head> node to add the script node to, but Opera is more strict and will give you an error. (Thumbs up, Opera! To begin with, the browsers tolerating such quirks got us into that lapse-of-standards trouble we're in today. I've read somewhere that (wildly guessing here), more than 50% of the browsers' source code deals with not properly nested tags, unclosed tags, and so on and so on programmer's mistakes made out of pure laziness)

DOM way after page load

The next test waits for the page to load completely before adding a script child to the HTML node. This is done by:

function afterload(){
    var which_script = Math.floor(Math.random() * 2) + 1 + '.js';
    include_dom(which_script);

}
	
window.onload = afterload;

Here's the test.

Javascript include on user demand

Now a bit more of a real life example - the javascript is included when the user performs an action (click). Both the DOM and the document.write methods are tested, only to prove that the DOM is better suited for such tasks. When you document.write after the page is loaded, you basically write to a new page and this is not what the user expects.

Here's the test #5.

Include once

Here I just wanted to try how a PHP-like include will work. In PHP there's include() and include_once(). include_once() means that if the file was already included, it should not be included again. This in my example is done by a simple array that is a list of all included files. Included using include_once(), that is. To accomplish this effect I also coded a Javascript equivalent of the PHP's in_array().

var included_files = new Array();

function include_once(script_filename) {
    if (!in_array(script_filename, included_files)) {
        included_files[included_files.length] = script_filename;
        include_dom(script_filename);
    }
}


function in_array(needle, haystack) {
    for (var i = 0; i < haystack.length; i++) {
        if (haystack[i] == needle) {
            return true;
        }
    }
    return false;

}

Here's test #6. In this test the .js files are included only once, on the first click. After that, nothing happens.

Conclusion

And that's it, this is the way (the DOM one) to include javascripts on the fly. Using this technique you can have only one <script src="..." ...> tag in your HTML source. You include one Javascript and it takes care of it's dependent scripts (libraries) and it also can include other scripts conditionally. Let's say (for the sake of the example, not that you should do it) you have a script that works in Mozillas and another one that works in IE. So you write one new script that checks the browser and this new script (using the DOM inclusion technique from above) checks for the browser and includes only the required of the two other scripts.

Wait a second...

Then I thought about this for a while and I realized that including new scripts on the fly is in essence another way of making a remote call, yes, the ever so popular remote scripting. In addition to the two techniques used for making remote calls - XMLHttpRequest (or AJAX) and using iframes, with this javascript DOM inclusion described above you can also make HTTP requests without reloading the page. Not that it's a viable alternative to XMLHttpRequest (no POST-ing, HEAD-ing or anything, just a GET), but still... something interesting.

As a proof-of-concept I did a PHP script that comes up with a random number between 1 and 100 and then outputs the result using a javascript alert(). My intent was to call this script as a javascript and do it several times par one page load. So I added some extra headers to

  1. Send a correct text/javascript header. Not that it's needed but still a good practice, FireFox is already picky when it comes to text/css for example;
  2. Prevent the php-javascript from being cached. OK, the cache prevention gets a little carried away (actually these headers are taken from php.net's manual), but ... you never know. The only needed header is:
    header("Cache-Control: no-store, no-cache, must-revalidate");
    It's needed by IE anyway. FireFox didn't cache the included script even with no cache-prevention headers and Opera cached even with all of them. For Opera I came up with a random junk as part of the GET request when a script name when it's called, just to make the script name unique.

So the PHP scripts is:

<?php
// javascript header
header('Content-type: text/javascript');
// Date in the past
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
// always modified
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
// HTTP/1.1
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);

echo 'alert(\'' . rand(1,100) . '\')';
?>

The JavaScript that calls this PHP script on the fly is using the same include_dom() function, only it adds this random key/value pair at the end of the script call url.

function include_rpc(script_filename) {
    script_filename += '?' + Math.random(0, 1000) + '=' + Math.random(0, 1000);
    var html_doc = document.getElementsByTagName('head').item(0);
    var js = document.createElement('script');
    js.setAttribute('language', 'javascript');
    js.setAttribute('type', 'text/javascript');
    js.setAttribute('src', script_filename);
    html_doc.appendChild(js);
    return false;

}

And so this proof-of-concept worked of FireFox (of course), IE (well, enything worth mentioning has to work on that browser) and Opera. There is a demo here. Every click on that list item that says "click" includes a php-generated Javascript on the fly which alerts a random number. So it behaves like a true RPC thingie - new files are HTTP-requested without the page being reloaded!

Like I said I don't see that as being a full-scale alternative to XMLHttpRequest, because it makes GET requests only and also it always returns javascript. What is being called using these javascript includes is a javascript, so any server-side script that needs to be called, has to return the results as javascript. Well, this can actually be handy sometimes. Using XMLHTTP you get XML which contains data you need and you have to access that data using DOM methods and technically translate the XML to javascript variable(s). In the JS include method above, the data returned is already a Javascript - it can be a JS function that does something on the document or it can be a JS variable (might as well be an XMLDoc JS variable). So because it doesn't necessarily return XML (although it can), this method has only AJA from AJAX -- the "asynchronous" and the "javascript" ;)

Resources

After I finished this posting I figured out I can search for similar articles on the web. Here are two that I found, created back in year 2002. It's again surprising how old the remote scripting techniques are (3 years is almost forever on the web), only that before Gmail most of the developers were ignoring them.

2006-10-23 update: In IE, I found a way to tell when the new script is done loading - described here.

2006-10-25 update: The cross-browser way to tell when a script is loaded is here.

Tell your friends about this post: Facebook, Twitter, Google+

177 Responses

  1. It is a great article …. just what I have been looking for. There is one thing though. It does not seem to work in Opera Version 7.23?

  2. I took what you had here for includes and added a few things:
    http://www.n-son.com/scripts/includes/Include.js
    http://www.n-son.com/scripts/includes/include.html

    You use Include() and Include.Once() to include files. The Include() function also checks the Include.Once registry so you can’t include a file with Include.Once and then include it with Include(). It also checks the head for a and will add the base url if it is a relative src for the javascript file.

  3. Thanks, Cristian!
    Well, I tested on the latest Opera 8.01 and it seemed OK. Is there anything special about Opera 7.23 (excuse my ignorance :oops: ) ?

  4. I don’t know anything about Opera :-) Opera 7.23 is just the one that i have … but rarely use. Anyway it is the one that I am testing up against.

  5. I read your article a few days ago and think it is really great (haven’t had time to comment till now). DOM is actually the method I used to use back in the day. I used to research Remote Scripting techniques heavily and this was the best at the time and learned a bit from http://www.ashleyit.com/rs/main.htm . I’ve made a Remote Scripted chatroom before using DOM RS with PHP. Then XMLHTTPRequest came along and now that is all I use when it comes to RS.

    Great article, glad to see this method is still being used :) Love it.

  6. Hi
    What a GREAT article…

    I have made some changes to loading also css external files. This is tested in IE 6, FireFox 1.x and Opera 8 (Opera prior to 8 doesn’t support XmlHttpRequest)
    **********************************************************
    The code can be used like this:

    include_once(“test.css”);
    include_once(“test.js”);
    loadajax(‘test.php’); // ajax XmlHttpRequest handling function

    *********************************************************

    //********************************************************
    //from http://www.phpied.com/javascript-include/
    //********************************************************
    var included_files = new Array();
    function include_once(script_filename) {
    if (!in_array(script_filename, included_files)) {
    included_files[included_files.length] = script_filename;
    include_dom(script_filename);
    }
    }
    function include_dom(script_filename) {
    var html_doc = document.getElementsByTagName(‘head’).item(0);
    t=script_filename.substring(script_filename.lastIndexOf(‘.’)+1);
    if (t==’js’){
    var file = document.createElement(‘script’);
    file.setAttribute(‘language’,'javascript’);
    file.setAttribute(‘type’,'text/javascript’);
    file.setAttribute(‘src’,script_filename);
    }else if (t==’css’){
    var file = document.createElement(‘link’);
    file.setAttribute(‘rel’,'stylesheet’);
    file.setAttribute(‘type’,'text/css’);
    file.setAttribute(‘href’,script_filename);
    }
    html_doc.appendChild(file);
    return false;
    }
    function in_array(needle, haystack) {
    for (var i = 0; i

  7. Nice one, Luis! Thanks for sharing!

    Have you tested run-time switching of CSS files using this technique?

  8. Hey Nathan, this is good, I never thought about the relative URLs.

    Sorry about your comment not appearing until now, I didn’t know that WP holds for moderation posts that have more links (therefore look spammy).

  9. Inspired by Luis’ comment, I tested including and switching CSS files on the fly. It worked! Here’s the test page.

  10. Hi Stoyan,

    I have prepared a test using these ideas with AJAX, but is too big to fit here. can you please send me a e-mail? I will send you the test files in a zip file (2.5 Kb).

    Luis

  11. Here’s a demo/test/proof-of-concept from Luis:
    http://www.phpied.com/files/jinc/Luis/test.html

    The demo shows how to use a combination of XMLHTTPRequest and the above DOM include method to include just about anything without reloading the page, namely:
    - an external JS file
    - an external CSS file
    - an external HTML file that also comes with its own JS and CSS

    Thanks Luis!

    All the files can be seen here, it’s the dir listing that also includes all the test files as a single zip archive.

  12. The only technique that works in Safari is the document.write one. If you want to support that browser you’ll have to hold off on the DOM way (which is nicer)

  13. Just read two articles on simmilar topic I thought people might be interested in on devshed written by Brian Vaughn. Link posted below

    http://www.devshed.com/c/a/PHP/PHP-and-JavaScript-Pooling-Your-Resources-continued/

  14. i think, if you have many requests on page, better not add new js to page, but just replace one, that was previously loaded.
    Consider this code:

    var js_node;
    function include_rpc(script_filename) {
        script_filename += '?' + Math.random(0, 1000) + '=' + Math.random(0, 1000);
        var html_doc = document.getElementsByTagName('head').item(0);
        var js = document.createElement('script');
        js.setAttribute('language', 'javascript');
        js.setAttribute('type', 'text/javascript');
        js.setAttribute('src', script_filename);
        if (js_node)
        {
           html_doc.replaceChild(js,js_node);
        }
        else
        {
           html_doc.appendChild(js);
        }
        js_node = js;
        return false;
    }
    
  15. One thought. I ran into this problem months ago and came up with some far-fetched solutions because I ran into problem after problem. Here’s the one that I ran into and am curious if you’ve managed to solve it with this.

    I’ve got some content that I want to load via Ajax:

    // foobar() is a function in foo.js
    alert(foobar());

    Happy funtime stuff

    Seems simple. My solution was to first create the DOM objects and point the src to foo.js then afterwards evalute the inline scripts. This ordering would always occur: first find the external references, load them, and then evaluate your inline scripts. In IE, surprisingly, this worked like a dream. But in Firefox, it actually loads foo.js in a separate thread! This creates some issues of trying to evaluate “alert(foobar())” before the “including thread” finished its task. So you’d actually get a foobar is not defined error since foo.js hadn’t finished loading yet.

    // psuedo-code for evaluation portion. load external *then* inline
    for( var i = 0; i

  16. My post was apparently cut off… the code bit was essentially

    1) Parse xmlhttp.responseText for script elements
    2) iterate over scripts, load all external bits using the DOM src= method above
    3) *then* eval all in-line script code

    I eventually stopped trying to find a solution and included all of my potential external scripts in the main page (the one making the Ajax calls). This doesn’t scale all that well, so I’d be interested if anyone else has solutions to this or if I’m missing something in this article that covers that. Thanks!

  17. I tried sig’s technique of using replaceNode() and it worked fine on Firefox, but got an Invalid Argument error in Internet Explorer.

    I’ve used replaceNode for other things in IE without any problems – does anyone know if there’s some special treatment of script elements in this regard? Or could it be because the parent is the head element?

  18. Alan, I haven’t tried this, but if replacing doesn’t work, you can try removing the old node, then appending the new one. Something like:

    if (js_node)
    {
    html_doc.removeChild(js_node);
    }

    html_doc.appendChild(js);

  19. Stoyan, I thought of that, but it gave me the same “Invalid Argument” error.

  20. Hi all.
    I have working in a project that will be a group of objects that it can manage CSS, makes MySQL querys and insert HTML tags without reload.
    My english is (very?) bad so i invite to you to visit the page project and help if you like.
    http://ntn.matware.com.ar/

    Greetings

  21. Hi again.
    I forget my mail address: maguirre@matware.com.ar

    Greetings

  22. One hint about invalid argument when using replaceNode(): if the element created under a certain document is used to replace a node in another document then this error occurs. Should use node created in the same document to replace other nodes.

  23. Hi

    Does anyone know how pass html table data from parent to a child form html table ? or maybe have a link

    Any kind of help is highly appericiated.

    Thanks

    Imran Hashmi
    http://www.visionstudio.co.uk

  24. Hi,

    Can someone tell the cons and props for

    window.eval(req.responceText)
    vs
    document.getElementById(‘container’).innerHTML=req.responceText;
    vs
    file=document.createElement(‘script’);
    file.setAttribute(‘src’,script_filename);

    ?

  25. jFlash 1.5 Released

    After more than a year of on-and-off development I finally got up the intertia to release a new version of jFlash. There are many changes in this release. Here is what is most important: JavaScript Code Clean-Up The real…

  26. Nice Idea, but there is no need for in_array function.
    Just use

    if( !included_files[script_filename] ){

    }

    By the way, you use in PHP too.

  27. Javascript Include Files

    I wrote a little Include library, based off of Stoyan Stefanovs code in his article about Javascipt include files.

    Its basically the same code with some improvements.

  28. Stoyan,

    My code also had a bug in the includeOnce function.
    The complete project, with unit tests can be found at http://weblog.freeopinion.org/files/include_js.tgz

  29. I’m running Safari 1.3.1, and the seven tests all pass.

    In Luis’ first test, Safari loads neither the linked stylesheet nor the external script.

    By the way, if XMLHttpRequest returns an entire HTML document, it’s invalid to import that into an existing HTML document, because then you’d have the new html/head/body inside the old body, or at the very least you’d have two title elements.

    If XMLHttpRequest returns HTML at all, it should probably be just a document fragment.

    Finally, I don’t think anyone has mentioned an important advantage of XMLHttpRequest over DHTML-RPC — it’s asynchronous. Using JS to load scripts is *dynamic*, but it’s not asynchronous — the parent script halts (and stalls the user session) until the loaded script completes. So it’s unsuitable for running time-consuming queries, but should work just fine for, oh, I don’t know… how about dynamic loading of script files? :-)

    Josh

    In general, it is safe and legal to kill your children and their children.

    — POSIX Programmer’s Guide

  30. http://xkr.us/code/javascript/include.js

  31. Your idea worked great until I included scripts that depend on each other.
    I can’t figure out how to “wait” until loading is complete on all included
    scripts before continuing.

  32. This guy use the same Stoyan’s method…

    Take a look at:
    http://www.phpit.net/article/ajax-php-without-xmlhttprequest/

    or
    http://ajaxextended.com

  33. I tested the script for “DOM way after page load” in IE for Windows 2000 and it didn’t work, but didn’t give any errors. Could someone tell me why this doesn’t work? Here is what I have:
    function include_dom(script_filename) {
    var html_doc = document.getElementsByTagName(‘head’).item(0);
    var js = document.createElement(‘script’);
    js.setAttribute(‘language’, ‘javascript’);
    js.setAttribute(‘type’, ‘text/javascript’);
    js.setAttribute(‘src’, script_filename);
    html_doc.appendChild(js);
    return false;
    }
    function afterload(){
    var which_script = ’1.js’;
    include_dom(which_script);
    }

    window.onload = afterload;

  34. L.Woland, there might be a problem if the html file is not properly structured. E.g. do you have a “head” tag to append to? Is it properly opened and closed and nested in an (one and only one) “html” tag?

  35. I’ve found an interesting er… bug from this code?

    I have the feeling it may be the different threads problem somebody mentioned earlier. As a side note, certain errors will cause script execution to fail but won’t alert the user to this fact, basically killing your script without being able to debug it, the problem I think LWoland had (maybe?)

    I have ScriptA included in my html files. ScriptA then includes librariesB & C. Then if I try and run any functions from LibraryB within ScriptA my function fails… but more helpfully it fails without any errors and simply stops execution at that point.

    Any ideas on that one?

  36. I’ve created a comparison between normal ajax and the createElement method. It can be found here: http://www.endeavorpub.com/uncharted/

  37. Hey there…
    first of all: great work – thanks a lot for inspiration :)

    suggestion: include_once could be improved: if it is used (as is) in two different js-files, which are both loaded by the same html page, the second one will overwrite the included_files-array initialized by the first one and therefore include the file again.

    if one is likely to come in a situation like that, he should either prepend the initialization like this:
    if(included_files != undefined) var included_files = new Array();

    …or (as I prefer, because it seems to be the “safer way” somehow) check for inclusion the dom way, like that:
    function include_once(filename) {
    var head = document.getElementsByTagName(“head”).item(0);
    var i;
    for(i=0; i

  38. sorry… obviously lower-thans are not supported here ;-)
    hope the entity works:

    function include_once(filename) {
    var head = document.getElementsByTagName(“head”).item(0);
    var i;
    for(i=0; i<head.childNodes.length; i++) {
    var n = head.childNodes[i];
    if(n.nodeName.toLowerCase() == “script” && n.getAttribute(“src”) == filename) return;
    }
    include_dom(filename);
    }

  39. [...] ingy. Sunday, February 12th Web Development Quickie Phpied.com has a great article on using JavaScript to dynamically include other JavaScript files.? It goes way beyond [...]

  40. excellent article! i was looking to see if there was a built-in way to do this in javascript, but this looks just as good! thanks!

  41. Andy Savage & L.Woland, maybe you overwrote your onload function later on? that would be a common pitfall…
    note: window.onload is overwritten by <body onload=”blah()”> too!

    scripts that need an onload function should always be working like that to ensure they work with other scripts too:

    var prevOnLoad = window.onload;
    window.onload = afterload;

    and somewhere within the afterload function:
    if(prevOnload != undefined) prevOnload();

    and better not use onload in the body tag…

    just an idea – hope this helps

  42. i have got two servers, In first server i will enter some fields which is done in PHP. in the other server which is totally simple Html page, the data which i have entered in the First server should get automatically updated in the second server without refreshing the total page, a part of the page should get automatically refreshed, can anyone give some idea about this

  43. I’ve just stumbled across another problem with the includes :(
    Who guarantees that the included script is completely loaded and all the more executed before proceeding with the including script?
    Obviously you cannot be sure of that, because I just managed to produce exactly this case (XP,IE6,SP2) having a JSP page which loads two external js files (say A.js and B.js) the old-style way (i.e. script tags), one of them doing two include_once calls (say C.js and D.js), and one of the included files doing another include_once in turn (say E.js).
    And that’s where error messages start to occur, when D tries to use a method in E.
    I wonder if anyone has found a solution for this problem, because I really like this include-thing – but I cannot use it, if it’s not 100% safe :-/

  44. This include/include_once idea is great, but it doesn’t require the js file to be fully loaded before continuing … The problem is to ascertain whether the file has loaded so the scripts are available.

    Let me give a simple AJAX application… I click a button which fetches a form and external javascript for the form (like tinymce or some other html editor). I want to grab the components, then load the page… calling a function within the newly included js file sometime gives an error (because the append doesn’t guarantee that the file has loaded).

    Any suggestions, maybe we could preload it somehow like images… I don’t like the idea of adding some flag var hasLoaded=true at the end in these library js files to guarantee it has loaded.

    Regards,

    monte

    {x:

    e.g.,

    // include once
    // HACKED UP FROM http://www.phpied.com/javascript-include/
    /*
    include_once(”test.css”,”css”);
    include_once(”test.js”,”js”);

    include(”testcss.php”,”css”);
    include(”test.php”,”js”);
    */

    var included_files = new Array();

    function include(script_filename,t)
    {
    included_files[included_files.length] = script_filename;
    include_dom(script_filename,t);
    }

    function include_once(script_filename,t)
    {
    if (!in_array(script_filename, included_files))
    {
    included_files[included_files.length] = script_filename;
    include_dom(script_filename,t);
    }
    }

    function include_dom(script_filename,t)
    {
    var head = document.getElementsByTagName(“head”)[0];

    if (t==”js”)
    {
    var file = document.createElement(“script”);
    file.setAttribute(“language”,”javascript”);
    file.setAttribute(“type”,”text/javascript”);
    file.setAttribute(“src”,script_filename);
    }
    else if (t==”css”)
    {
    var file = document.createElement(“link”);
    file.setAttribute(“rel”,”stylesheet”);
    file.setAttribute(“type”,”text/css”);
    file.setAttribute(“href”,script_filename);
    }
    head.appendChild(file);
    return false;
    }

    function in_array(needle, haystack)
    {
    for (var i = 0; i

  45. Thank you very much for publishing this solution. I’ve been looking for this “document.write(“”) in IE” bug solution for a long time.

  46. The problem with loading script via DOM is the async problem. How I’ve coped with this is to use a timer to poll for a variable/function/object/etc in the required script. Once it’s found, we know the script has loaded. Thus:
    ———–
    function loadScripts() {
    // test1.js contains function “testMe()”
    // test2.js contains function “testMe2()”
    // test3.js contains var “biteMe = true”
    var scripts = ['test1','test2','test3'];
    var head = document.getElementsByTagName(‘head’)[0];
    for (n = 0; n

  47. Hmmm…let’s try that again
    ———–

    function loadScripts() {
    // test1.js contains function “testMe()”
    // test2.js contains function “testMe2()”
    // test3.js contains var “biteMe = true”
    var scripts = ['test1','test2','test3'];
    var head = document.getElementsByTagName(‘head’)[0];
    for (n = 0; n
    ———–

  48. Last time lucky…
    ———–
    function loadScripts() {
    // test1.js contains function “testMe()”
    // test2.js contains function “testMe2()”
    // test3.js contains var “biteMe = true”
    var scripts = ['test1','test2','test3'];
    var head = document.getElementsByTagName(‘head’)[0];
    for (n = 0; n < scripts.length; n++) {
    var tag = document.createElement(‘script’);
    tag.type = ‘text/javascript’;
    tag.src = scripts[n] + ‘.js’;
    head.appendChild(tag);
    }
    // Now we wait till the 3 scripts have loaded
    wait4Scripts();
    }

    function wait4Script() {
    if (typeof(testMe) != ‘undefined’ &&
    typeof(testMe2) != ‘undefined’ &&
    typeof(biteMe) != ‘undefined’) done();
    else setTimeout(wait4Scripts, 10);
    }

    function done() {
    alert(‘test.js has loaded’);
    }
    ———–

  49. This page was very helpful. I found the format functional and pleasant.
    Thank you.

  50. Hi there,
    finally, I had to give up on this include-stuff :(
    I have already sworn a lot when I had to cope with a lot of getBytesLoaded-loops in flash, I don’t want to go through all that in Javascript again *ouch* ;-)
    I also tried around with a functionality where each loaded script registers with an include-handler when completely loaded, so that others scripts can be notified when included scripts are loaded, this worked fine, until problems arose with scripts that needed to wait for window.onload too.
    So, instead of spending much time for building a huge (but probably not really elegant) framework in order to catch any case, I got back to do it the old-style way…
    If anyone has found a smart&safe solution, please let us know, I really do like the approach.

  51. I’d just like to comment on the flaw with document.write and how it writes to a new page. This is not actually the case — in reality, it replaces the current page contents with the new code. However, executing it deeper either using void() or by putting it in your own function should prevent the page from being blanked and _just_ output the text. :)

  52. Sorry if I’m just being thick here, but (why) does “The DOM Way” function have to return false?

  53. I’m depressed – I’ve been planning to write an article about this, but you beat me to it!

  54. You can do something similar using:

    - a stylesheet: http://zingzoom.com/ajax/ajax_with_stylesheet.php

    - an image: http://zingzoom.com/ajax/ajax_with_image.php

  55. Hi,

    Stumbled across this and realised its just what I needed! Was looking for a simple way to trigger importing my own JS into pages, primarily to use my scripted DOM Inspector across other sites. Combined this into a bookmarklet, et voila! Greasemonkey lite ;)

  56. Hey,

    Great stuff!!! :) Pure-PHP already pointed this out above, but I wanted to expand on the point. As he mentioned, you don’t need the in_array() function at all. JavaScript arrays are really hashes. So you could rewrite your function like this:

    function include_once(script_filename) {
    if (!included_files[script_filename]) {
    included_files[script_filename] = true; // really non-”false” value
    include_dom(script_filename);
    }
    }

    Since the included_files array is only used to test existence, the script names can be used for the keys, and the element values can be anything that don’t evaluate to “false” (i.e. false, 0, “”, null, undefined) when tested.

    Anyway, thanks for the great tips!! You’re a true scientist! :)
    Gooch

  57. Apology for a second post, but the comment in my above code was supposed to read:
    // really any non-”false” value

    Example of hash:
    var aHash = new Array();
    aHash[“me”] = “Goocher”;
    aHash[“you”] = “Phpied”;
    alert(aHash[“me”]); // pops up “Goocher”
    alert(aHash[“you”]); // pops up “Phpied”

    Also cringed at my English above in the last post; meant to use the words “doesn’t evaluate” above, not “don’t evaluate”. Nobody cares but me, I’m sure… but anyway… ;)

    Thanks!!! Was looking for a way to dynamically include js files. This is great.

  58. thanks a bunch! I’ve been trying to write some type checking libraries, but don’t want to bog down the page with ones that are irrelevent.

    I’ve made an attempt to objectify this i bit. So, I’ll include that below. It’s interesting to note that js libraries are removed from the rendered source, but from what I could test so far, anything still running, will continue on it’s merry way. I made a timer, and it kept rolling on after I removed the js library from inclusion. nifty, right.

    //js
    var js_includes = new Array();

    function JSManager(){
    this.included = js_includes;
    this.include = js_include_once;
    this.remove = js_remove_include;
    }

    function js_include_dom(script_filename) {
    var html_doc = document.getElementsByTagName(‘head’).item(0);
    var js = document.createElement(‘script’);
    js.setAttribute(‘language’, ‘javascript’);
    js.setAttribute(‘type’, ‘text/javascript’);
    js.setAttribute(‘src’, script_filename);
    html_doc.appendChild(js);
    return false;
    }

    function js_include_once(script_filename) {
    if (!in_array(script_filename, js_includes)) {
    js_includes[js_includes.length] = script_filename;
    js_include_dom(script_filename);
    }
    }

    function js_remove_include(scriptname){
    var docScripts = document.getElementsByTagName(‘script’);
    for(var i=0;i

  59. the rest

    function js_remove_include(scriptname){
    var docScripts = document.getElementsByTagName(‘script’);
    for(var i=0;i

  60. sorry, you guys can just get it yourselves i guess :P

    http://www.ito-y.com/dynamicInclude.js

    -g

  61. [...] Всяка имплементация на AJAX има своята клиентска и сървърна част. От потребителска страна е нужена основно JavaScript поддържка в браузъра (каквато има в повечето инсталирани такива). И това всъщност е основното изискване. Останалото е технологията от сървърна страна, която може да бъде всякаква: от чист HTML, през CGIки на Perl, Python… до PHP, ASP.NET и т.н.. Попаднах на два примера за съвсем простичка реализация на AJAX без всякакви допълнителни щуротии: тук и там. Разбира се, описаните подходи са малко несериозни, макар че на много места биха свършили страхотна работа. След огъня, колелото и картофите, цивилизацията достигна до XML. И тъй като напоследък всичко е XML, логично бе заявките от браузъра да се подават до сървърното приложение (каквото и да е то) през XML, давайки възможност от страната да стои каквото и да е обработващо XML. За целта в JavaScript се появи обектът XMLHttpRequest. [...]

  62. [...] Yahoo’s web service can return XML as everybody else, but it can also return serialized PHP and also JSON. Using the JSON option you can make a simple XMLHTTPRequest and get all the content JavaScript-ready, without the headaches of getELementsByTagName() or other DOMmy methods to wrestle that XML tree. The problem here is that you’re requesting a file from a different domain, so the browser won’t allow it. Workaround – a simple PHP script to serve as a proxy. Oooor (as we said we don’t need no stinkin’ server) you can use the dynamic JavaScript includes (discussed here) to do the request. As a result you get a working solution with JS only. [...]

  63. Hi everyone. I’ve tested some examples from this website.
    This functions do work.

    But I am thinking of this issue.

    Will it be possible to “unload” javascript, with all it’s values and stuff.

    Like unset in php… Destroying all object/variables that script we want to remove has loaded.

    Switching of css styles works, but each time user clicks to switch element, new css is appended to the head of document.

  64. The scripts with anticache code during loading.
    added:
    + “?rand=”+Math.random()

    function include_dom(script_filename) {
    var html_doc = document.getElementsByTagName(‘head’).item(0);
    t=script_filename.substring(script_filename.lastIndexOf(‘.’)+1);
    if (t==’js’){
    var file = document.createElement(‘script’);
    file.setAttribute(‘language’,'javascript’);
    file.setAttribute(‘type’,'text/javascript’);
    file.setAttribute(‘src’,script_filename + “?rand=”+Math.random());
    }else if (t==’css’){
    var file = document.createElement(‘link’);
    file.setAttribute(‘rel’,'stylesheet’);
    file.setAttribute(‘type’,'text/css’);
    file.setAttribute(‘href’,script_filename + “?rand=”+Math.random());
    }
    html_doc.appendChild(file);
    return false;
    }

  65. Alexandar, check this posting:
    http://www.phpied.com/javascript-to-find-your-yahoo-ranking/
    There I’m unsetting the previous include, before adding a new one.
    Hope this helps.

  66. Hi Stoyan I am glad You responded so quickly.

    Basically this is all really not a PHP-like include function.

    Real PHP include function, lets You do this:
    $something=Array(“file1.php”,”file2.php”……..)
    for($i=0;$i

  67. Oh :’( my code seems not to be there.

    I am having problems with dynamic script loading and premature execution.

    I will post here more later.

  68. Ok, so here is what I want to do. I want a real PHP-like include function.

    To load content of external file and eval the code from it!

    Problem is in that loading of external files, so here is what I found:
    http://www.rgagnon.com/jsdetails/js-0034.html

  69. Don’t use setAttribute() and it’ll work just fine in Safari. The setAttribute() method has entirely different purposes.

    See include.js for a proper, debugged implementation.

  70. Wolfgang Krpelan

    The problem with this whole approach seemingly is that its not standard-based and obv. depends on good-will of future browser-versionists.
    Seems not suitable for serious business to me at this time.

  71. Hmm, looking at this, IMHO it looks to be working entirely inside the w3c DOM calls. I fail to see how you came to the conclusion you have Wolfgang.

    The setAttribute method is standard for setting attributes of elements in the DOM, of which the src attribute is one. Surely it is all just XML (of which XHTML is a subset). Which version of Safari was that, and what “entirely different purposes” did Brad Fults mean?

    The basic system works fine in firefox, konqueror and nautilus for me. I have not tried it in Opera, Safari or IE yet though.

    The biggest problem, and it could be a showstopper, is the problem of not knowing when you have loaded.

    My possible solution would be to have the javascript libraries call a function in the include system to register they are loaded. This would be done with their name. The application requiring to load it may then register a callback, which is stored as an associative member in an array.

    The library then calls back the standard function in the include (after using an if to check if it has been included from said library). The standard function checks the associative array, and if there was a callback registered, calls it.

    This solution seems so far to work, but I am still working out the kinks. I will be posting some code once I am happier with it.

    Danny

  72. Hi Danny, thanks for your comment, keep us posted :thumbsup:

  73. Here is a function which uses the DOM approach and if it fails uses document.write brute force:

    function includeJs(scriptName) {
    	var html = document.getElementsByTagName('head').item(0) || document.body;
        var js = document.createElement('script');
        js.setAttribute('language', 'javascript');
        js.setAttribute('type', 'text/javascript');
        js.setAttribute('src', scriptName);
        if (!html.appendChild(js)) {
    		document.write('');
        }
    }
    
  74. the previous post was stripped…
    here is the document.write argument:
    <script src=”‘ + scriptName + ‘” type=”text/javascript”></script>

  75. everybody know that JS is unprotected and easy to find out…. but watch out now:

    if you put additional line to include():
    js.setAttribute(‘id’, ‘my_protected_script’);

    and put at the end of your included script commands:
    ….
    var head = document.getElementsByTagName(‘head’).item(0);
    var script = document.getElementById(‘my_protected_script’);
    head.removeChild(script);

    you will notice that scripts work but any saving page to disk or debugging
    in IE will NOT show the source !!

    Source of included script remain in browser memory short time and after
    removeChild they stay in compiled form so they still work without document’s DOM definition.

    regards to all !!
    cs

  76. I could freakin kiss you for this little jem:

    script_filename += ‘?’ + Math.random(0, 1000) + ‘=’ + Math.random(0, 1000);

    Forget hair, I was about to pull my teath out trying to get safari to accept more that one request.

    Thanks!

  77. Great article! The DOM way is the only method to switch js code in a single Ajex interface.

  78. Great !

    Can you remove previously loaded scripts ? I just fond your article and didn’t have time yet to experiment !

    I think this can be used in conjunction with PHP or ASP to load data from the server by replacing a previously loaded file with another one !

  79. Hi Kelumden, yes, you can unload scripts. Chreck my experiment here:
    http://www.phpied.com/files/yjsonrank/yjsonrank.html

    Basically you just keep a reference to the las loaded script element (let’s say it’s named “js”) and then, to unload, you do:
    document.getElementsByTagName(‘head’).item(0).removeChild(js)

  80. Hey all. Cool discussion.

    You guys should check out Ajile. It’s an awesome js library that makes dynamic js includes really easy, plus it unloads the scripts so your source is protected, well cloaked anyway. It doesn’t use the XMLHttpRequest approach either so you can include scripts from anywhere!

    You can do:

    – Load(“http://someotherdomain.com/coolscript.js”);

    And for the gurus/neatfreaks:

    – Import(“com.mydomain.AwesomeScript”);

    – ImportAs(“MyAlias”, “com.mysite.NamingConflict”);

    It’s at http://ajile.iskitz.com/ with examples, docs and even a support group too.

  81. Looking over this article, it seemed very interesting but I moved on to Ajile. They solve the above problem about checking to see if it’s loaded using a listener. The listener determines if it’s loaded and then I think can execute a function when its loaded, so sort of like XMLHttpRequest. It pretty much does everything you’re doing above and more with namespaces which is very useful if you’re trying to write structured code. However, it doesn’t seem like there is much of a community behind the project — and perhaps there needs to be.

  82. This does not work with Google Maps javascript. It seems to hang if one tries to do a dynamic include on it. Anyone have any ideas as to why this is and potential remedies to the problem? Both this method and the include method of ajile seems to cause this problem.

  83. I’ve got a question…

    If web browsers detect there’s on a single page several js included, but they’re the same file.
    Do they download the same file again and again? I suppose so, because you have an “include_once” javascript method.

    I’ve got that question because i’m coding in .net and i use user components (independant snippets of code) that they include a js lib. Then you can build a page with several snippets (all are the same, it just changes its id). I want my user components to be “independant”: just drag and drop them, you dont have to include js on your own, but i was wondering if the browser parses every <script …> and download the js withouth noticing it’s the same all the time.

    I’ve been looking up this question this morning and i’ve found (after posting on your blog) that in .net you have somehow a “include_one” as you have developed, but in server side ( http://www.eggheadcafe.com/articles/20041016.asp)
    I may use your approach as it’s quite simple and i dont like controlling js by .net code

    Very good article!!

  84. I did a little test and yes, the browsers do include the same file every time.

    I called this function in a link onclick event

    function includeMe() {
    
        var script_filename = 'jsinc.js';
    
        var html_doc = document.getElementsByTagName('head').item(0);
        var js = document.createElement('script');
        js.setAttribute('language', 'javascript');
        js.setAttribute('type', 'text/javascript');
        js.setAttribute('src', script_filename);
        html_doc.appendChild(js);
    }
    

    and in jsinc.js I have

    alert(‘Here I am – ‘ + Math.floor(Math.random() * 100));

  85. You could implement searching to see if it’s already been included but that would be expensive as it’s not an id that you can pick, but that’s do-able. So essentially, before adding you would search to see if a certain file has already been added and then add the file.

  86. Hi Sami,
    Regarding the dynamic include problem with Google Maps API & Ajile:

    It appears for some reason not completely clear right now that the Google Maps API script needs to be loaded before Ajile’s. You’ll need to have at least 2 script tags in your HTML file to work around the issue. The first script tag should point to the Google Maps API location and the second to Ajile’s location, in that order.

    Much of Google’s API appears to be obfuscated so I didn’t spend much time trying to figure the root cause, but using the aforementioned technique I’ve been able to create a working example of Ajile & Google Maps in harmony :-)

    http://ajile.sourceforge.net/tests/google/

    If anyone finds issues or incompatabilities with Ajile please post a message at:

    http://help.ajile.iskitz.com/

    Happy scripting!

  87. how do i include a reference (maybe an include command) to a .js page into another .js page?

  88. Hi Samuel,
    The short answer is to do:

    Load(“script2.js”);

    inside of script1.js where you have 2 scripts, script1.js and script2.js.

    In more detail what you could do is this:

    mypage.htm – HTML page
    mypage.js – Script for HTML page
    common.logic.js – Second script to be included by 1st script

    inside of mypage.js you do: Load(“common.logic.js”);

    besides that all you need to do is include the Ajile module in a script tag in your mypage.htm file. Ajile will automatically load the mypage.js file which in turn will automatically load the common.logic.js file.

    Check http://ajile.iskitz.com/ for more information.

    Good luck,
    Michael

  89. We are running a very popular website (low millions of page views per day) that includes other js files with document.write. This seem to be working for a few months but then complaints started coming in that the homepage wasn’t visible for

  90. less than 1% of users. After a few days of painful investigation we discovered that Norton Personal Firewall was blocking the request for the included js file, w/o notifying the user. This may also be the case with other ad-blockers so…BEWARE!

  91. Norton is detecting the content type as sent from the server and will block text/javascript or alike.
    So you may want to send a custom “Content-type: text/myscript” header instead.

  92. [...] http://www.phpied.com/javascript-include/ [...]

  93. You know you could always load up an img and tie retrieving code to the onload event… it will always fire when the documents fully loaded.

  94. Guys, you may be interested in this:

    http://cows-ajax.sourceforge.net/

    that uses the same principle to get around the ‘same-origin’ policy ‘issue’ that HXR and Iframes have.

  95. [...] This is a follow up to my article (the most popular on my blog based on the comments) about the JavaScript includes, the technique to include new .js files after the page is loaded, by using DOM to create a new script tag. The problem that is discussed in the comments is how to find out when/if the new script was actually downloaded. Here’s a solution (IE only!). [...]

  96. That’s great. As a matter of fact, I thought of exactly the same and google web sites for the method of inclusion some JS scripts on demand and I got a page of a guy that has made the same.

    Cheers.

  97. [...] JS includes – the saga continues… [...]

  98. [...] Javascript includes – yet another way of RPC-ing – Javascript files can be included and executed on the fly — either when loading the page or in run-time. This means that HTTP requests are made without the use of XMLHttpRequest or iframes. This post provides a trail of my experiments… [...]

  99. [...] Javascript includes – yet another way of RPC-ing- Javascript files can be included and executed on the fly — eitherwhen loading the page or in run-time. This means that HTTP requests aremade without the use of XMLHttpRequest or iframes. This post provides atrail of my experiments… [...]

  100. Glad i found this article! fixed my problems with some nasty ad tag code which can now be replicated for diff banner positions on the same page ;)

  101. Interesting

  102. [...] I wanted to host the Firebug files on my hard-drive and then use a javascript dynamic include to load firebug.js via a bookmarklet. This way I would be able to load the firebug console every time I want it, on any page. Unfortunatelly IE’s security policy won’t allow it. Then? [...]

  103. Very nice! Thanks.
    You can add a function call to execute when the file is loaded, like this:

    var js;
    // functionCall - e.g., "myFunction(foo, bar)"
    function include_js(file, functionCall) {
        var html_doc = document.getElementsByTagName('head')[0];
        js = document.createElement('script');
        js.setAttribute('type', 'text/javascript');
        js.setAttribute('src', file);
        html_doc.appendChild(js);
    
        js.onreadystatechange = function () {
            if (js.readyState == 'complete') {
                alert('JS onreadystate fired');
            }
        }
    
        js.onload = function () {
            eval(functionCall);
        }
        return false;
    }
    
  104. [...] http://www.phpied.com/javascript-include [...]

  105. [...] En general, ademas de mejorar el soporte PEAR aumentando sus capacidades, he incluido FormHandler (sistema para hacer y gestionar formularios) , asi como multiples mejoras en la forma de incorporar librerias al proyecto. Ahora tengo que abordar tambien como meter algo de Javascript sin complicar el uso… Lo proximo que tengo que hacer es incluir algunas funcionalidades Ajax y ver como demonios hacer documentación, aunque esto ultimo lo tengo complicado voy demasiado pillado de tiempo con el codigo en si (que uso como todos sabeis en mis proyectos profesionales), asi que por ahora y hasta que algun voluntario/a/os/as se animen a documentarla, si teneis alguna duda/pregunta, escribidme a rcarrillo@metsuke.com asunto savLib -loquesea-. [...]

  106. [...] phpied.com » Blog Archive » Javascript includes – yet another way of RPC-ing (tags: javascript include) [...]

  107. I liked the idea of checking the src attribute to see if a script had already been injected, but checking the src attribute doesn’t work if you also append the random number to stop caching “‘?rand=’+Math.random()” since every url will appear different.

    Instead I suggest giving the injected scripts an id attribute and checking the id attribute for duplication. In those cases where you deliberately want to inject the same script twice, then assign an empty string to the id.

    I’ve also modified the addition of the random number, making its addition a parameter, and getting it to work in cases where the URL already contains other parameters.

    The code follows below, and there is a working example at http://www.acutetechnology.com/projects/public/ajax/inject.html

    function include_once(script_filename, script_id, randomise) {
    // Inject javascript or css unless one exists with the same id attribute
    var head = document.getElementsByTagName(‘head’).item(0);
    for(var i=0; i

  108. (trying again using <)

    Yahoo document an interesting variation here: http://developer.yahoo.com/common/json.html

    They provide an API that returns search results as an object encoded in JSON. As a variant you can append “&callback=ws_results” to the URL and they will return to you the JSON string enclosed by your callback function name and parentheses: “ws_results()”. ws_results is the name of a javascript function already present in your code. Then by placing src= inside the tags results in your ws_results function running with the JSON object as its parameter.

    They have a working example at the above URL. For a working example visit http://www.acutetechnology.com/projects/public/ajax/inject.html

  109. (apologies to moderator – I intended to submit two postings – the code in the first one failed so I replaced less than signs, but then pasted in my SECOND posting rather than the modified first posting. So here is my modified first posting…)

    I liked the idea of checking the src attribute to see if a script had already been injected, but checking the src attribute doesn’t work if you also append the random number to stop caching “‘?rand=’+Math.random()” since every url will appear different.

    Instead I suggest giving the injected scripts an id attribute and checking the id attribute for duplication. In those cases where you deliberately want to inject the same script twice, then assign an empty string to the id.

    I’ve also modified the addition of the random number, making its addition a parameter, and getting it to work in cases where the URL already contains other parameters.

    The code follows below, and there is a working example at http://www.acutetechnology.com/projects/public/ajax/inject.html

    function include_once(script_filename, script_id, randomise) {
      // Inject javascript or css unless one exists with the same id attribute
      var head = document.getElementsByTagName('head').item(0);
      for(var i=0; i<head.childNodes.length; i++) {
        var n = head.childNodes[i];
        var nType = n.nodeName.toLowerCase();
        if ((nType == 'script' || nType == 'link') && script_id != '' && (n.id == script_id)) {
          // duplication
          return;
        }
      }
      include_dom(script_filename, script_id, randomise);
    }
    
    function include_dom(script_filename, script_id, randomise) {
      // inject a js or css file into the current DOM
      var t = script_filename.substring(script_filename.lastIndexOf('.')+1);
      if (randomise) {
        if (script_filename.lastIndexOf('?') == -1) {
          script_filename += '?rand='+Math.random(); 
        }
        else {
          script_filename += '&rand='+Math.random();     
        }
      }
      var head = document.getElementsByTagName('head').item(0);    
      if (t == 'css'){
        // this is a CSS file
        var file = document.createElement('link');
        file.rel = 'stylesheet';
        file.type = 'text/css';
        if (script_id != "") {
          file.id = script_id;
        } 
        file.href = script_filename;
      }
      else {
        // here for file that end in .js, or anything else that we want to execute 
        // within a script tags
        var file = document.createElement('script');
        file.language = 'javascript';
        file.type = 'text/javascript';
        if (script_id != '') {
          file.id = script_id; 
        }
        file.src = script_filename;
      }
      head.appendChild(file);  
      return false;
    }
    
  110. Thanks Charles!

    For the Yahoo way, I like it very much too, I played with it here

  111. Michael Bendio’s suggestion (12 December 2006) of using js.onload and js.onreadystatechange to fire events when the scripts had loaded seemed interesting. I tried it quickly with these observations:

    With IE6 and IE7 both the onload and onreadystatechange events fired when I loaded CSS files, but neither events fired when I loaded javascript files.

    With Firefox the onload event, but not the onreadystatechange event, fired when I loaded javascript files. Neither event fired when I loaded CSS files.

    Can anyone else can shine more light on this?

  112. @Charles:
    This might shine some light:
    http://www.thomasfrank.se/easier_than_ajax.html

  113. I was searching for an equivalent of PHP in_array() when I hit this article. Nice one and great ideas.

    I just wanted to post a simpler in_array() function. I am not sure if it is more efficient, but it is straight forward and simple. Here it goes:

    function in_array(needle, haystack)
    {
    return((‘|’+haystack.join(‘|’)+’|').indexOf(‘|’+needle+’|') != -1)
    }

    Can anyone advise me on the efficiency part?

  114. [...] Javascript includes – yet another way of RPC-ing [...]

  115. [...] A very cool AJAX like JavaScript using “SCRIPT” element to load the content can be found here   [...]

  116. Is there a technique by which we can unload a dynamically uploaded javascript ?

  117. [...] AJAX Tutorials A comprehensive list (over 140!) of tutorials on AJAX, JavaScript and other web development topics. Submit a tutorial that’s not already here. Be sure to check out my posts under the Tutorials category as well for the latest tutorials. Javascript Motion Tweenby Philippe Maegerman 10 Realistic Steps to a Faster Web Siteby Alexander Kirk 60 More AJAX Tutorialsby Max Kiesler addEvent() considered harmful – an article from quirksmode.org AJAX and scripting Web services with E4X, Part 1 – “Get an introduction to ECMAScript for XML (E4X), a simple extension to JavaScript that makes XML scripting very simple. In this paper, the authors demonstrate a Web programming model called Asynchronous JavaScript and XML (AJAX)…” AJAX and scripting Web services with E4X, Part 2 – We have successfully used E4X to invoke Web services, and now we would like to provide Web services using E4X. AJAX and Session Race Conditionsby Harry Fuecks AJAX Design Patterns – “Is this tutorial any different from the others? Well yes and no, it is different in being a tutorial on how to design and build a complete site and not just some fancy little details like how to turn caching in AJAX off or how to create a fancy widget.”by Christian Decker AJAX FAQ for the Java Developerby Greg Murray AJAX file upload Ajax for Designers Ajax for Java developersby Philip McCarthy Ajax for Java developers: Ajax with Direct Web Remotingby Philip McCarthy Ajax for Java developers: Java object serialization for Ajaxby Philip McCarthy Ajax Patterns: Concurrent Document Loader Pattern – useful in cases when you need to load multiple XML documents concurrently and get notified when all requests are completed.by Alex Iskold Ajax using XMLHttpRequest and Struts – The Ajax concept is based around something called the XMLHttpRequest component. … However, XMLHttpRequest does. make the underlying Ajax concept far … Ajax using XMLHttpRequest and Struts example online – an interesting post with several opinions from TheServerSide.com J2EE community AJAX, JSON, PHP, and Flex Togetherby Mike Potter AJAX, RemoteScripting.Net, Script Callbacks and Other Goodnessby Peter A. Bromberg, Ph.D. AJAX: Building a Spy AJAX: Developing Interactive Web Contentby Prasanna Srinivasan AJAX: How to Handle Bookmarks and Back Buttonsby Brad Neuberg Ajax: It’s not all about XMLHTTPRequest (part I) – “…there are other technologies in the Ajax realm that should not be overlooked and XSLT is one of them.” AJAX: Usable Interactivity with Remote Scriptingby Cameron Adams AJAX:Getting Started – mozilla developer center article AjaxCookbook.org – from Brett Taylor @ Google. Alternate Ajax Techniques, Part 1by Nicholas C. Zakas Alternate Ajax Techniques, Part 2by Nicholas C. Zakas An Ajax Primer: Don’t Fire Your HTML Crew Yet – Forrester report An XML to JSON webserviceby Mark McLaren Asynchronous JavaScript and XML (AJAX) with Java 2 Enterprise Edition Baking Ajax into Struts and Spring MVC BJAX With Greasemonkey – “how to do BJAX (Browser Extension and AJAX) with Greasemonkey on Firefox”by Dietrich Kappe Build Your Own AJAX Web Applications (Sample Chapters)by Matthew Eernisse Building a Photo Tagging Site using ASP.NET 2.0, LINQ, and Atlasby Scott Guthrie Call SOAP Web services with Ajax, Part 2: Extend the Web services client Client Callbacks in ASP.NET 2.0 Client Side Validation Using the XMLHTTPRequest Object – article from 15seconds.com with an emphasis on ASP Considering Ajax, Part 1: Cut through the hypeby Chris Laffra Consuming Amazon’s Web API Directly with Javascript (via JSON and XSLT) Cook Computing: Ajax and XMLHttpRequest Tutorial – Ajax and XMLHttpRequest Tutorial. Web applications which dynamically update their web pages without refreshing the whole page are in the news a lot these … Creating AJAX and Rich Internet Components with JSF – Part 1 – based on, and contains excerpts from, the book Pro JSF: Building Rich Internet Components by Jonas Jacobi and John Fallows, published by Apressby Jonas Jacobi, John Fallows Creating a secure login system using XMLHttpRequest Creating Custom Events with BLOCKED SCRIPT Decoupling Designing RIAs For Search Engine Accessibility – Backbase article, June 2005by Jeremy Hartley Developing Ajax Applications That Preserve Standard Browser Functionalityby Mark Schiefelbein Developing AJAX Applications the Easy Wayby Joe Walker Developing PHP the Ajax way, Part 2: Back, Forward, Reload – We will use JavaScript to create a history stack for the Ajax photo gallery built in Part 1 of this two-part “Developing PHP the Ajax way” series.by Mike Brittain Developing Web Applications with Ajax, Pt. 4 – “you’ll learn how to submit information through forms without reloading the page”by Jonathan Fenocchi Devise Web 2.0 applications with PHP and DHTML, Part 1: Cook up your own with these recipesby Jack Herrington Drag and drop sort order with Scriptaculous Dynamic HTML and XML: The XMLHttpRequest Object – good overview article from developer.apple.com Dynamic Loading and Rendering with YUI’s Menu and TreeView Controlsby Eric Miraglia Ease the integration of Ajax and Java EE – Successfully mix asynchronous and synchronous communication modelsby Patrick Gan Errors and AJAX – xml.com articleby Joshua Gitlin Excerpt: Ajax in Action, Managing Events and the Model Exploiting the XmlHttpRequest object in IEby Amit Klein Explorer 7 beta – preliminary notesby Peter-Paul Koch Fixing AJAX: XmlHttpRequest Considered Harmfulby Jason Levitt Fixing the Back Button and Enabling Bookmarking for AJAX Apps Floatutorial: Step by step CSS float tutorial Flooded with XML: Stemming the tideby Andrew Nash, Reactivity Gaia Window Ajax Tutorial Generate user-click heatmaps using JS and Rubyby David el Dia Graded Browser Supportby Nate Koechley Guide to Using XMLHttpRequest (with Baby Steps) from WebPasties – Baby Steps The XMLHttpRequest object is a handy dandy JavaScript object that … Although the XMLHttpRequest object might sound complex and different from … Hacking Protopage and Backpack Hands On: Understanding AJAXby Joshua Eichorn How To Create an RSS Aggregator with PHP and AJAX How to paginate, sort and search a table with Ajax and Rails How to use Atlas as an Ajax callback library…by Jay Kimble Implementing Mutual Exclusion for AJAXby Bruce Wallace Including AJAX Functionality in a Custom JavaServer Faces Component Incorporating XML Content Into Your Web site (ASP) Integrating AJAX with the JMX Notification Framework Introduction to Scriptaculous Effects Javascript Benchmarking – Part I Javascript Benchmarking – Part II JavaScript Improvements in IntelliJ IDEA 5.1 – my editor of choice offers several nice JavaScript improvements Javascript includes – yet another way of RPC-ing – Javascript files can be included and executed on the fly — either when loading the page or in run-time. This means that HTTP requests are made without the use of XMLHttpRequest or iframes. This post provides a trail of my experiments… BLOCKED SCRIPT Passing by Value or by Reference Mapping website visitors in real timeby Vegard A. Larsen Mastering Ajax, Part 1: Introduction to Ajax Mastering Ajax, Part 2: Make asynchronous requests with JavaScript and Ajaxby Brett McLaughlin Mastering Ajax, Part 3: Advanced requests and responses in Ajax – Gain a complete understanding of HTTP status codes, ready states, and the XMLHttpRequest objectby Brett McLaughlin Mastering Ajax, Part 4: Exploiting DOM for Web responseby Brett McLaughlin Mastering Ajax, Part 5: Manipulate the DOM Microsoft’s Reference to the XMLHttp object My Top 12 CSS Articles/Tricks of 2005 On JSONby Steve Maine Optimizing the Client Side – This article discusses the role that Asynchronous JavaScript plus XML (AJAX) played in helping Iconix software developers build DrugMatrix. It covers the alternatives considered and why we decided on an AJAX-enabled Rich Internet Application (RIA).by John Calvin OutPost: Post Back Over XmlHttpby Troels Wittrup Jensen Painless JavaScript Using Prototype – a great introduction to the Prototype libraryby Dan Webb Peeling Back the Interface of the Yahoo! Home Page Beta Performance Impacts of AJAX Development – Using AJAX to Improve the Bandwidth Performance of Web Applicationsby Christopher L Merrill Podcast+Text: The AJAX Web Architecture Preloading Data Preloading Data with Ajax and JSONby Ryan Campbell Rails HowTo: Pluralizing Really easy field validation with Prototype Realtime Form Validation Using AJAXby Greg Murray Remote Scripting with AJAX, Part 1 – XML.com articleby Cameron Adams Remote Scripting with AJAX, Part 2 – XML.com articleby Cameron Adams Remote Scripting with IFRAME Running XMLHttpRequest with Java – a simple example using a Google api servlet Sarissa to the Rescue – an article from XML.com So how do you code an AJAX Web page? – See hands-on examples for creating lighter, faster interactive sitesby Edmond Woychowsky Speeding Up AJAX with JSONby Sean Kelly Spring and DWR revisited Ten Things Yahoo! Is Already Doing with the YUI Library – “Inspired by our own Dustin Diaz’s recent post (”15 Things You Can Do with Yahoo UI“) on the new frontend-developer journal Vitamin, we wanted to share with you ten things Yahoo! is already doing with YUI.”by Eric Miraglia The AJAX response: XML, HTML, or JSONby Peter-Paul Koch The Ajax transport method – Discover three Ajax data transport mechanisms (XMLHttp, script tags, and frames or iframes) and their relative strengths and weaknesses.by Jack D Herrington The Code Project – AJAX DropDownList – ASP.NET – Custom DropdownList that utilizes AJAX to populate its content and implements … This is the page that handles the request from xmlHttp and returns the … The Hows and Whys of Degradable Ajaxby Ryan Campbell The Right Way to do Ajax is Declarativelyby Duncan Cragg Top 10 custom JavaScript functions of all time Tuning AJAXby Dave Johnson Understanding and Solving Internet Explorer Leak Patterns – MSDN articleby Justin Rogers Use AJAX Components in Seam Applicationsby Michael Yuan Use Ajax to build an RSS readerby Mr. Jack D Herrington Using a Servlet with JavaServer Faces Technology and AJAX – This entry discusses strategies that add AJAX support to JSF components by introducing a servlet to process the AJAX requests.by Mark Basler Using Ajax from Perlby Dominic Mitchell Using AJAX to track user behavior – interesting blog Using AJAX with Java Technology Using AJAX with XMLHTTPRequest and Struts (PDF) Using JavaServer Faces Technology with AJAX Using PhaseListener Approach for Java Server Faces Technology with AJAX – how to use the PhaseListener approach to incorporate AJAX functionality into a JSF applicationby Mark Basler Using Ruby on Rails for Web Development on Mac OS X – an article from developer.apple.com Using Ruby on Rails for Web Development on Mac OS Xby developer.apple.com Using the XML HTTP Request object Using the XMLHttpRequest Object and AJAX to Spy On Youby Earle Castledine Very Dynamic Web Interfaces – article from XML.com Web browser CSS support – includes detailed information about CSS support in major web browsers What Every Webmaster and Web Developer MUST Know About Ruby on Rails and AJAXby Matt Lightner What’s the best way to integrate Ajax into a Java webapp? XForms: An Executable Pattern Languageby Mark Birbeck XML in Firefox 1.5, Part 1: Overview of XML featuresby Uche Ogbuji XML in Firefox 1.5, Part 2: Basic XML processingby Uche Ogbuji XML in Firefox 1.5, Part 3: JavaScript meets XML in Firefox – Learn how to manipulate XML in the Firefox browser using JavaScript featuresby Uche Ogbuji XML Responses and AJAXby Jayaram Krishnaswamy XML Tutorial – Free HTML,XHTML,CSS,JavaScript,DHTML,XML,DOM,XSLT,ASP,ADO,SQL tutorial and web building primer from W3Schools. XML/Http -> AJAX -> Atlas – AJAX incorporates XMLHttp but is not limited to IE. Now it is “hold the presses” at Microsoft who is planning to roll out ATLAS, explained here by Scott … XMLHTTP notes: readyState and the events – some great info from quirksmode.org XMLHttpRequest Tutorial XMLHttpRequest Usability Guidelines Published Feb 17 2007, 07:50 AM by AjaxMatters [...]

  118. [...] Javascript includes – yet another way of RPC-ing [...]

  119. [...] N.B. rasmus pointed out a nice, in depth article that goes though several techniqes to do this. If you are interested, check it out. (The DOM way doesn’t work in Safari). [...]

  120. [...] <“AJAX” sem XMLHTTPRequest [...]

  121. I wrote a JavaScript #include using Prototype:

    http://www.forgeniuses.com/?p=14

  122. Great tutorial.

  123. [...] As life is a google-search for the terms “load javascript dynamically” gives, as a first result, this article: Dynamically Loading External JavaScript Files and, after some more digging around, Javascript includes – yet another way of RPC-ing. Searching and digging are nice. [...]

  124. This makes sure the page is loaded prior to firing the callback function. Fix for event handling:

    function include_dom(script_filename, oCallback) {
    var html_doc = document.getElementsByTagName(‘head’).item(0);
    var js = document.createElement(‘script’);
    js.setAttribute(‘language’, ‘javascript’);
    js.setAttribute(‘type’, ‘text/javascript’);
    js.setAttribute(‘src’, script_filename);
    if (oCallback != null){
    // most browsers
    js.onload = oCallback;
    // IE 6 & 7
    js.onreadystatechange = function() {
    if (this.readyState == ‘loaded’) {
    oCallback();
    }
    }
    }
    html_doc.appendChild(js);
    return false;
    }

  125. [...] По этой теме можно почитать на http://www.phpied.com/javascript-include/ [...]

  126. [...] How do you make the request? With JavaScript includes, meaning you use DOM methods to sreate a new <script> tag and add it to the head of your page. The src attribute of the new script tag points to the Y! service, a longish kind of URL with a bunch of parameters. [...]

  127. Has anyone else tried js includes on Firefox 3 beta?

    It seems that the window.onload event is called prior to the loading of included js files. Its a bit hit and miss – sometimes the js is loaded in time and all works fine. Try it for yourself with 2 js files – the first file includes the second file and then uses a var that is in the second file. Firefox 2 works. Firefox 3 beta comes up with an error because the var is not defined … then try refresh a few times and it will work now and then.

  128. [...] As life is a google-search for the terms “load javascript dynamically” gives, as a first result, this article: Dynamically Loading External JavaScript Files and, after some more digging around, Javascript includes – yet another way of RPC-ing. Searching and digging are nice. [...]

  129. [...] Nevertheless, this now leaves me with a problem. The script has pushed the main menu code up to a staggering 18KB, with about 14 javascripts which takes 6 seconds to load off my hobbled test server – and it’s not even finished! Clearly a little refinement is needed and I thought I had it with this with a useful little script from http://www.phpied.com/javascript-include/. It’s a powerful tool that can append javascripts dynamically by linking them into the document as children to the header element. Not that that any of my build so far resembles a document. [...]

  130. I use to have a function similar to this but had some issues with being able to run the code right away…

    This is the solution I came up with

    http://www.exit12.org/archives/12

  131. [...] YUI Blog just published my first article, I’m so proud. It’s about loading JavaScript in non-blocking fashion, because JavaScripts, they, you know, like, block downloads. Luckily, there’s an easy fix – DOM includes, which I’ve previously discussed, discussed and discussed. [...]

  132. Great tips, thanks.

  133. Works great. Thanks.

  134. Just went to the Safri Dev site and got this header code for PHP to prevent caching.
    All in all, I think this RPC approach is simple and brilliant. It’s much better than my work around that I was
    planning on doing (which was using img src and reading the buffer which would have actually been data -
    stupid idea if not impossible).

    On another note, I’ve never liked XML. It’s bloated and verbose. Don’t get me wrong, I use XML all the time, but for most situations it’s totally overkill. I start feeling queezy everytime I think of all the code I have to write to handle a seemingly simple XML task that turns into an epic trama.
    I guess when someone else if flipping the nickle, your best not to complain and use the most time consuming approach as possible.

    Anyways, here’s what I got from apple, should alleviate any caching issues on most browsers.

    header(“Expires: Mon, 26 Jul 1997 05:00:00 GMT”); // Date in the past
    header(“Last-Modified: ” . gmdate(“D, d M Y H:i:s”) . ” GMT”); // always modified
    header(“Cache-Control: no-store, no-cache, must-revalidate, max-age=0″); //HTTP/1.1
    header(“Cache-Control: post-check=0, pre-check=0″, false);
    header(“Pragma: no-cache”); // HTTP/1.0

    ——————— Here’s the whole page working – with php ————-

    RPC without loading up page header

    function getdata()
    {

    phpfile=’test.php’;

    testval=document.getElementsByTagName(‘script’);

    for(x=0; x<testval.length; x++)
    {
    if(document.getElementsByTagName(‘script’)[x].name=”time”)
    {
    document.getElementsByTagName(‘script’)[x].setAttribute(‘src’, phpfile);
    document.all.item(‘url’).value=testval.length+” “+x;
    }
    else
    {
    var js = document.createElement(‘script’);
    js.setAttribute(‘type’, ‘text/javascript’);
    js.setAttribute(‘src’, phpfile);
    js.setAttribute(‘name’, ‘time’);
    document.getElementsByTagName(‘HEAD’)[0].appendChild(js);
    }
    }
    document.all.item(‘url’).value+=” :”+testval.length;
    }

    ———- PHP ————-

    <?php
    // javascript header

    header(“Expires: Mon, 26 Jul 1997 05:00:00 GMT”); // Date in the past
    header(“Last-Modified: ” . gmdate(“D, d M Y H:i:s”) . ” GMT”); // always modified
    header(“Cache-Control: no-store, no-cache, must-revalidate, max-age=0″); // HTTP/1.1
    header(“Cache-Control: post-check=0, pre-check=0″, false);
    header(“Pragma: no-cache”); // HTTP/1.0

    $date=date(“F j, Y, g:i:s a”);
    echo <<

  135. [...] http://www.phpied.com/javascript-include [...]

  136. [...] phpied.com – Javascript includes – yet another way of RPC-ing [...]

  137. Great work! This is a very innovative way to include information. I’ll definately be making use of this! (with credit to you of course :) )

  138. [...] execute in that. …. Did a quick search on "javascript include" and came up with this: http://www.phpied.com/javascript-include/ Scroll down a bit to "The DOM way" – that’s what I did, and it worked nicely. There are a [...]

  139. [...] Javascript includes – yet another way of RPC-ing / phpied.com  Link to this page  Link to this page Copy the code below to your web site. x  [...]

  140. [...] [upmod] [downmod] phpied.com » Blog Archive » Javascript includes – yet another way of RPC-ing (www.phpied.com) 0 points posted 10 months, 1 week ago by jeethu tags webdev ajax include [...]

  141. [...] where i was including something got to run multiple times, and this caused problems. So i found the solution on phpied.com. So here it is, the php include_once equivalent for [...]

  142. I have problems with with the js file download via the ‘once’ method when the filw contains something like
    var ErrorAspect = { anything }, and I want to immediately after the script is inserted access ErrorAspect. When the enclosing script ends, the ‘include once’ script excecutes and I am able to access ErrorAspect
    – enclosing script
    —– include once
    — end of enclosing script

    — after unspecified time – I have had it fail is I don’t wait enout
    ErrorAspect.bar = “works”

    Using the AJAX way, I can have a call execute and access ErrorAspect – but the method seems slow, and I am noy sure that Error Aspect has executed. I was forced to include a time out loop until ErrorAspect is defined.
    Thanks for helping with this problem

  143. 真是一篇好文章,可惜我英语只能看,不能说。

  144. [...] DOM you can create a new LINK element and a new SCRIPT element and append them to the HEAD. For images – it’s a one-liner new [...]

  145. Hi. I’m trying to use your idea to dynamically load scripts at runtime just when I need them, without bloating the html page with script tags.

    I need to load a script like this:

    function myClass () {}

    (function() {
    alert (“myClass succesfully loaded”);
    myClass.myMember = “value”;
    myClass.myMethod = function () { doSomething(); };
    }());

    When I invoke include_dom(“myClass.js”) the alert “myClass succesfully loaded” is fired so the script is loaded and executed, but if I try to access ‘myClass’, it is undefined.

    How could you explain that? Maybe the variables are not added to the global scope?

  146. [...] [...]

  147. I thought I’d post a word of warning.

    This is a good method of loading javascript libraries but should not be used to fetch sensitive data because javascript files can be loaded cross-domain. This means that a different site can download and use the data so long as the browser is authorized to access it. This is called a Cross Site Request Forgery (CSRF attack).

    For an example, take a look at this article http://directwebremoting.org/blog/joe/2007/01/01/csrf_attacks_or_how_to_avoid_exposing_your_gmail_contacts.html

  148. [...] preloading JavaScript files, use the JavaScript include_DOM technique and create a new <a title="Look up the tag in the SitePoint HTML Reference." [...]

  149. Thanks for your samples. Just tried and it works for me!

  150. Oxyhives Active Ingredient…

    [...]Javascript includes – yet another way of RPC-ing / Stoyan’s phpied.com[...]…

  151. видеоуроки по wordpress…

    [...]Javascript includes – yet another way of RPC-ing / Stoyan’s phpied.com[...]…

  152. That is very fascinating, You’re an overly professional blogger. I’ve joined your rss feed and stay up for in the hunt for extra of your great post. Additionally, I have shared your site in my social networks

  153. My mate and i also ended up only speaking about this specific matter, the woman happens to be normally wanting to prove us absolutely wrong! I feel gonna demonstrate to her this web site publish and also apply the item within a very little!

  154. xplodergames…

    [...]Javascript includes – yet another way of RPC-ing / Stoyan’s phpied.com[...]…

  155. great post about, however! i really don’t want to be so negative however i believe that the website could look better if you had a bit of red in it ;) No…, you don’t need to agree… this really is merely my humble view. Thank you for a excellent post anyway! =) Best regards, Wunsch

  156. Pediatric Dentists Omaha…

    [...]Javascript includes – yet another way of RPC-ing / Stoyan’s phpied.com[...]…

  157. make hair grow faster…

    [...]Javascript includes – yet another way of RPC-ing / Stoyan’s phpied.com[...]…

  158. rpc server is unavailable xp…

    [...]Javascript includes – yet another way of RPC-ing / Stoyan’s phpied.com[...]…

  159. 777vid…

    [...]Javascript includes – yet another way of RPC-ing / Stoyan’s phpied.com[...]…

  160. ebook…

    [...]Javascript includes – yet another way of RPC-ing / Stoyan’s phpied.com[...]…

  161. [...] The function is taken from this article [...]

  162. [...] have quite a few posts here on this blog about this stuff. Starting with something I considered an interesting hack to emulate PHP's require(). This was posted in 2005. (2005! That's [...]

  163. Thanks! Very helpful!

  164. I’m now not sure where you’re getting your info, but good topic. I must spend a while studying much more or working out more. Thanks for wonderful information I used to be in search of this info for my mission.

  165. Howdy this is somewhat of off topic but I was wanting to know if blogs use WYSIWYG editors or
    if you have to manually code with HTML. I’m starting a blog soon but have no coding skills so I wanted to get advice from someone with experience. Any help would be greatly appreciated!

  166. I don’t know whether it’s just me or if perhaps everyone else
    experiencing issues with your website. It appears like
    some of the written text in your content are
    running off the screen. Can someone else please comment and let me know if this is happening
    to them too? This might be a issue with my internet browser because I’ve had this happen previously. Cheers

  167. Water often is used as a base for your favourite low carb smoothie;
    it owns the minimum amount of carbs of most -infact zero.
    But rather than scold them into eating their fruits and vegetables, I find that being creative works much nicer.
    cup frozen strawberries, and one scoop vanilla protein powder in a blender and blend until smooth and
    frosty.

  168. Thanks for another amazing report. Exactly where else could any one obtain that variety of facts in this particular best means of creating? I own a powerpoint presentation pursuing 7 days, that i’m to the find such information.

  169. Aw, this was aan ncredibly good post. Taking a few minutes and actual effort to create a
    very good article… but what can I say… I hesitate a whole lot and never seem to get anything done.

  170. The art department is one of the most unique areas
    in the film industry, focused around production design, set design, prop development, and
    the general look of the environment and objects. This discourse is amplified in Tota Maina, where in addition to variations in natural light were added variations which correspond
    to emotional motivation rather than any sense of logic.
    If you’re thinking all you have to do is go out and look for a location
    and come back and report to the location manager, you’re wrong.

  171. Hey there! This is my first visit to your blog!
    We are a team of volunteers and starting a new initiative in a community in the same niche.
    Your blog provided us beneficial information to work
    on. You have done a marvellous job!

  172. Admiring the time ɑnd energy үou put into your site ɑnd in depth iոformation ʏou offer.
    It’s ɡood to come acrosѕ a blog every օnce in a while that isn’t the same
    outdated rehashed material. Excellent read! ӏ’ve bookmarked
    your site ɑnd ӏ’m including yοur RSS feeds
    to my Google account.

  173. Good post! We will be linking to this particularly grea content on
    our site. Keep up the good writing.

  174. We arre a gaggle of volunteers and starting a brand new scheme in oour
    community. Your web siute provided us with useful information too ork on.
    You’ve performed an impressive process and our whole community shall be grateful to you.

  175. I’m curious to find out what blog platform you have
    been working with? I’m having some small security issues with my latest site and I would like to find something more
    risk-free. Do you have any recommendations?

  176. Hi there it’s me, I am also visiting this website
    regularly, this website is truly nice and the visitors are really sharing good thoughts.

  177. Hiya! Quick question that’s completely off topic. Do you know how to make your
    site mobile friendly? My web site looks weird when browsing from my iphone.
    I’m trying to find a theme or plugin that might be able to fix this problem.
    If you have any recommendations, please share. Appreciate it!

Leave a Reply