Jens
Jens

Reputation: 1517

Conditional javascript loading

For my backend I want to automatically load javascript files when it detects certain elements. Here is an example:

if($('.wysiwyg').length>0) {
     include('javascript/ckeditor/ckeditor.js');
     $(".wysiwyg").ckeditor();
}

But when I execute the code I get $(".wysiwyg").ckeditor is not a function because it seems the browser is still loading or parsing the javascript file that was included on the line before. If I put an alert popup right before the function it does work because it "pauzes" the script I guess and gives it time to load the file.

Is there a way I can know when the file is actually loaded so that the followed code can be executed?

EDIT: Seems that I asked this question a bit too soon. I found out the e.onload property for a callback function that solved this problem. This is my function now if others might stumble upon the same problem:

function include(script, callback) {
    var e = document.createElement('script');
    e.onload = callback;
    e.src = script;
    e.type = "text/javascript";
    document.getElementsByTagName("head")[0].appendChild(e);
}


if($('.wysiwyg').length>0) {
    include('javascript/ckeditor/ckeditor.js', function() {
        $(".wysiwyg").ckeditor();
    });
}

Upvotes: 4

Views: 8719

Answers (5)

nbk
nbk

Reputation: 1992

You can also try YepNope - a conditional javascript loader

yepnope is an asynchronous conditional resource loader that's super-fast, and allows you to load only the scripts that your users need.

Upvotes: 2

strings28
strings28

Reputation: 158

When you're using jQuery with promises you can use a modified version of the above code like so:

function include(srcURL) {
    var deferred = new $.Deferred();
    var e = document.createElement('script');
    e.onload = function () { deferred.resolve(); };
    e.src = srcURL;
    document.getElementsByTagName("head")[0].appendChild(e);
    return deferred.promise();
}

Then you can use the above code with a '$.when(include('someurl.js'))' call. This will let you have

  1. The global window context (which you need for CKEditor)
  2. The ability to defer executing other code until the when resolves
  3. A script that doesn't require a callback and a context for that to be passed because jQuery is handling that with the promises functionality it includes.

I hope this helps someone else who is looking for more than a callback, and multiple scripts to be loaded with jQuery's promises/deferred functionality.

Upvotes: 2

gion_13
gion_13

Reputation: 41533

Why not use the built in ajax-based getScript?
It also has a callback mechanism that allows you to execute some code only after the required script has been succesfully loaded :

function include(script,callback){
    $.getScript(script, function() {
        if(typeof callback == 'function')
        callback.apply({},arguments);
    });
}

and then you can use it in such a manner:

if($('.wysiwyg').length>0) {
    include('javascript/ckeditor/ckeditor.js',function(){
        $(".wysiwyg").ckeditor();
    });
}

Upvotes: 3

Senad Meškin
Senad Meškin

Reputation: 13756

You can do it this way

$(document).ready(function()
{
 if($('.wysiwyg').length>0) {
       $('head').append('<script language="javascript" src="javascript/ckeditor/ckeditor.js"></script>');
     $(".wysiwyg").ckeditor();
}

});

Upvotes: 0

Related Questions