Hi Alex,

I could be completely misreading that code, and if I am, apologies in
advance.  It *looks* like you're trying to create a queue where you'll
only load one script file at a time, and that you're first downloading
each script via Ajax.Request and then separately appending a script
tag to the page header to tell the browser to download it.  I'm
guessing you're thinking at that point it'll be in cache.  I wouldn't
take that bet. :-)

The browser will maintain a queue of requests anyway (typically
processing two at a time, although I *think* browsers only process one
script download at a time because script order can be important --
can't find a reference for that, though, so I may be wrong), you don't
have to do it yourself.  But again, doing it this way -- synchronously
-- will completely lock up the browser's UI during the process, which
from the name "lazy loader" doesn't sound like what you're trying to
achieve.

I don't think your problem is with the Ajax.Requests not being
synchronous.  They probably are. But that doesn't mean that your DOM
additions are handled synchronously by the browser.  The browser may
need a moment when script isn't running before it actually processes
things like script tags.  Then of course, there's also the download of
the script itself (by the browser, as it may not be in cache), which
is definitely not synchronous to your DOM manipulation.

Also:  In your Ajax.Request, you're setting evalScripts to true, but
you're using it to load a JavaScript file rather than an HTML file.
That setting is to tell Prototype to evaluate any script within
<script> tags in the loaded content.  The JavaScript files won't have
any <script> tags.  If you want to eval the content, just do that
directly by eval'ing the response text.  But if you do *that*, there's
no need to add the script tags to the document's head and you may well
end up with errors if you do, as you'll effectively load the script
twice.

These articles on the unofficial wiki may help:

http://proto-scripty.wikidot.com/prototype:tip-scripting-dynamically-loaded-elements
http://proto-scripty.wikidot.com/prototype:how-to-load-scripts-dynamically

And this one on Ajaxian:

http://ajaxian.com/archives/a-technique-for-lazy-script-loading

If you really want to create a one-script-at-a-time queue, you can do
that without locking things up.  For instance, you can build a list of
scripts to download (as you are) and then download them via
Ajax.Request *asynchronously*, where the completion handler eval's the
one it got and then triggers the load of the next one.  For example:

function loadScripts(ary)
{
    processScriptQueue(ary.reverse());
}
function processScriptQueue(queue)
{
    var url;

    url = queue.pop();
    new Ajax.Request(url, {
        onSuccess: function(transport) {
            eval(transport.responseText);
        },
        onComplete: function() {
            if (queue.length > 0)
            {
                processScriptQueue(queue);
            }
        }
    });
}

(See how each completion chains to the next, without being
synchronous.)

There's a "gotcha" with using eval() to load scripts, however:
Functions declared in the boring old fashioned way ("function foo()
{ ... }") don't end up as properties of the global object, so you
can't later call those functions.  (You can write them as "foo =
function() { ... }" and they will get added to the global object
because of the Horror of Implicit Globals[1], but that only works if
you're in control of the script you're loading.)  There are clever
ways to make them get added, but they get browser-specific[2].

But all in all, I'd stick with letting the browser do it, just add the
script tags to the header.

[1] http://blog.niftysnippets.org/2008/03/horror-of-implicit-globals.html
[2] http://ajaxian.com/archives/evaling-with-ies-windowexecscript

FWIW & HTH,
--
T.J. Crowder
tj / crowder software / com


On Nov 6, 2:52 pm, "Alex Mcauley" <[EMAIL PROTECTED]>
wrote:
> i want it to be transparent hence the syncronous request ... so the function
> that calls the dependencies waits to continue untill the scripts that it
> requires are loaded ....
> I have it inserting a script into the dom properly but if i try to call the
> function in the test script it doesnt work
>
> -- Code
>  loadDependency : function(e) {
>    var req=new Ajax.Request(e, {
>               evalScripts: true,
>                 method: 'post',
>             asynchronous:false,
>         onComplete : function(res) {
>              var scriptTag = document.createElement("script");
>              scriptTag.setAttribute("type", "text/javascript");
>              scriptTag.setAttribute("src", e);
>                  
> document.getElementsByTagName("head")[0].appendChild(scriptTag);
>              $(scriptTag).update(res.responseText);
>     }
>
>     });
>  },
> lazyLoader : function(type,files) {
>   var url=new String(document.location);
>   if (url.charAt(url.length - 1) == "/") //remove trailing slash
>    {
>       url = url.substring(0, url.length - 1);
>    }
>
>   // url now holds the domain name // this is all because IE and ff differ
> on echoing sources
>
>   var loaded    = new Array();
>   var toLoad    = new Array();
>   var dependenciesArray = new Array();
>   var f=files.length;
>
>   for(i=0;i<f;i++) {
>    toLoad.push(url+files[i]);
>   }
>
>   $$('script').each(function(e) {
>    if($(e).readAttribute('src')) {
>     if($(e).readAttribute('src').indexOf("http") < 0) {
>      //alert($(e).readAttribute('src'));
>      loaded.push(url+$(e).readAttribute('src'));
>       } else {
>      loaded.push($(e).readAttribute('src')); // now the shit has the fuckin
> URL in it
>     }
>    }
>   });
>
>     var needsLoading=array_diff(toLoad,loaded); // array diff works fine
>     alert(needsLoading.length);
>          for(m=0;m<needsLoading.length;m++) {
>
>       alert(needsLoading[m]);
>      loadDependency(needsLoading[m]);
>
>      }
>
>   helpMe(); // this is in the loaded script (which has 3 lines in it!!) and
> doesn't work
>
>  },
>
> Above is the 2 parts to the script ...
> As you can see the 1st one gathers all the scripts in the DOM and appends
> them with the current URL (because Firefox and Inernet Explorer get the
> sources differently - Firefox adds the domain to the start of some of the
> scripts even though i havent put that as the source, only the relative path
> ... this fixes everything to add with a domain path)
>
> It takes the things that need to be loaded as an array -- Here
> var files = [
> '/resources/includes/client/effects.js','/resources/includes/client/scriptaculous.js','/resources/includes/client/f2.js'];
> lazyLoader('script',files);
>
> and adds domain to the path preceeding so i can match whats what in the 2
> arrays and not potentially load something thats already there...
>
> array_diff then returns me an array of what is missing from what is loaded
> and a loop on the array carries out supposedly `syncronous` ajax requests to
> load them into the head of the document ...
>
> It loads them fine and i can see the script source get added in firebug but
> when i goto call the function from f2.js (which is loaded properly) it
> returns "helpMe() is not defined" as a firebug error even though i can see
> it exists in the DOM ....
>
> So my theory is that if the request is synchronous then helpMe cannot be
> executed untill it is placed in the DOM...
>
> perhaps synchronous requests are removed from the latest prototype build
>
> Thanks
>
> Alex
>
> ----- Original Message -----
> From: "T.J. Crowder" <[EMAIL PROTECTED]>
> To: "Prototype & script.aculo.us" <prototype-scriptaculous@googlegroups.com>
> Sent: Thursday, November 06, 2008 2:41 PM
> Subject: [Proto-Scripty] Re: Building a lazy Loader
>
> Hi Alex,
>
> Can you post the offending code?
>
> Ideally, though, it makes for a more responsive UI if you allow the
> request to be asynchronous and handle the remainder of your logic in
> the onSuccess callback.  Synchronous requests basically lock up the UI
> of the browser.
> --
> T.J. Crowder
> tj / crowder software / com
>
> On Nov 6, 2:33 pm, Jeztah <[EMAIL PROTECTED]> wrote:
> > Hi guys and gals ... today i am building a lazyLoader based on
> > prototype
> > ....
>
> > Its already working except i assumed i could do a synchronous request
> > so
> > nothing further in the javascript function is executed untill the
> > request
> > has finished ... it seems that asynchronous : false; is not wokring
> > as i
> > expected in the Ajax options .. am i expecting to much from the
> > response to
> > hijack my function untill it has finished its XHR then let my script
> > continue what it was doing ?
>
> > I asumed this was a good idea as it would workout into a nice
> > dependency
> > module for certain scripts ...
>
> > Any ideas ?
>
> > ta
>
> > Alex
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to