Dynamically adding JavaScript and CSS using a resource-tracking object type

This is a quick demonstration of a few techniques in basic JavaScript: creating a custom JavaScript object type with properties and methods; dynamically adding both JavaScript and CSS references in a cross-browser-safe way; adding JavaScript async; and adding inline JavaScript and CSS. The resource loader tracks added resources, to ensure that they are loaded only once. Try it for yourself (open your browser’s developer tools to see logging output).

// A JavaScript type which manages references to scripts and stylesheets
function ResourceManager() {
  var addedReferences = {};
  var addedResources = {};
  
  this.isLoggingEnabled = false;
  
  this.referenceExists = function(url) {
  	if (url in addedReferences) {
    	this.log('Resource ' + url + ' already added');
      return true;
    }
    else return false;
  }
  
  this.resourceExists = function(text) {
  	if (text in addedResources) {
    	this.log('Text resource already added');
      return true;
    }
    else return false;
  }
  
  this.addScriptReference = function(url, addAsync, addDeferred) {
    if (typeof(url) == 'undefined' || this.referenceExists(url)) return;
    this.log('Adding script reference: ' + url + (addAsync ? ' [async]' : '') + (addAsync ? ' [deferred]' : ''));
        
    var script = document.createElement('script');
    script.src = url;
    if (addAsync) script.async = true;
    if (addDeferred) script.defer = true;
    document.head.appendChild(script); 
    
    addedReferences[url] = url;
  };
  
  this.addScript = function(text) {
    if (typeof(text) == 'undefined' || this.resourceExists(text)) return;
    this.log('Adding script');
      
    var script = document.createElement('script');
    script.appendChild(document.createTextNode(text));
    document.head.appendChild(script); 
    
    addedResources[text] = text;
  };
  
  this.addStyleSheetReference = function(url) {
    if (typeof(url) == 'undefined' || this.referenceExists(url)) return;
    this.log('Adding script reference: ' + url + (addAsync ? ' [async]' : '') + (addAsync ? ' [deferred]' : ''));
    
    var ss = document.createElement('link');
    ss.rel = 'stylesheet';
    ss.type = 'text/css';
    ss.href = url;
    head.appendChild(ss);
    
    addedReferences[url] = url;
  };  
    
  this.addStyleSheet = function(text) {
    if (typeof(text) == 'undefined' || this.resourceExists(text)) return;
    this.log('Adding style sheet');
    
    var ss = document.createElement('style');
    ss.type = 'text/css';
    
    if (ss.styleSheet){
      ss.styleSheet.cssText = text;
    } else {
      ss.appendChild(document.createTextNode(text));
    }
      
    document.head.appendChild(ss);  
      
    addedResources[text] = text;
  };    
    
  this.log = function(message) { if (this.isLoggingEnabled) console.log(message); };
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s