Robyflc
Robyflc

Reputation: 1209

How to elegantly add javascript/css on demand?

In my actual project, the users have the option to click a button in order to enter in an "edit mode" for their websites. After clicking the button, I have to download several JS and CSS files and I was doing it using the following code:

//Start edition mode
(function(){
    $.get('/helpers/edit/v/edit.php',function(data){
        $(data).appendTo('body');
        var css = '/helpers/edit/css/edit.css';
        $.get(css,function(data){
            $('<link/>')
                .attr({
                    'rel':'stylesheet',
                    'href':css
                }).appendTo('head');
            $("body").trigger("editReady");
        });
    });
})();

It works fine but now I need to insert more JS and CSS files and if I just keep nesting jquery get requests the code will become ugly and hard to mantain, which I want to avoid and shows me that this is probably not the best way to accomplish the task.

I also tried to use Yep Nope (which I'm already using in other parts of the project) inside the first get request but it seems not to work (I receive no error messages but it just doesn't work).

Does anyone have an idea of how to do this in a way that doesn't get so ugly and, mainly, is easy to mantain (considering that I have to trigger an event when all the JS/CSS are properly included)?

Thanks in advance!

Upvotes: 2

Views: 1691

Answers (3)

Kundan Singh Chouhan
Kundan Singh Chouhan

Reputation: 14282

I guess you can create an array of css and js file path and load it on iterating them i.e.

$.get('/helpers/edit/v/edit.php',function(data){
    $(data).appendTo('body');
    var css = ['mycss1.css','mycss2.css','mycss3.css'];
    $.each(css,function(index, elem){
       $('<link/>')
            .attr({
                'rel':'stylesheet',
                'href':elem
         }).appendTo('head');
    });

    var js = ['myjs1.js','myjs2.js','myjs3.js'];
    $.each(js,function(index, elem){
       $('<script></script>')
            .attr({
                'type':'text/javascript',
                'src':elem
         }).appendTo('head');
    });

    $("body").trigger("editReady");

});

Hope this will help.

Upvotes: 1

niiru
niiru

Reputation: 5112

I had a similar issue loading JSON from multiple sources recently. I modified that code and came up with this. The gist of it is to loop through get requests to your various URL's and then trigger your "editReady" event when the number of requests completed is equal to the number of URL's in the data_urls array (i = data_urls.length).

I originally wrote this in CoffeeScript so it's possible that I messed up a bracket or something somewhere...

function() {
  var data_urls = ['/helpers/edit/v/edit.php', '/helpers/edit/css/edit.css'];
  var i = 0;
  var _i, _len;
  for (_i = 0, _len = data_urls.length; _i < _len; _i++) {
    $.get(data_urls[i], function(data) {
      if (data_urls[i].match(/\.php/).length > 0) {
        $(data).appendTo('body');
      } else if (data_urls[i].match(/\.css/).length > 0) {
      $('<link/>')
        .attr({
          'rel':'stylesheet',
          'href':css
        }).appendTo('head');
      }
      i += 1;
      if (i == data_urls.length) {
        $("body").trigger("editReady");
      }
    });
  }
} 

Upvotes: 1

user753676
user753676

Reputation:

You can use a script loader like head.js http://headjs.com/

Seems require.js fits your needs: http://requirejs.org/

Also mentioned: LabJS http://labjs.com/ and YepNope http://yepnopejs.com/

Alternatives to YepNope and LabJS

YepNope seems to be very easy, there are the functions injectJs()and injectCss

yepnope.injectJs("jquery.js", ...
yepnope.injectCss("print.css", ...

Upvotes: 1

Related Questions