First, I want to start off by saying that there are plenty of JS libraries that provide the ability to add scripts to the page such as jQuery. The purpose of this article is to present an alternative function whose sole purpose is to add scripts (JSON-P or otherwise) to a page.

The following is the code for an addScript function which can either add static scripts or server generated scripts such as those used for JSON-P:


/**
 * Adds a script to the page which pulls its code from the specified URL.
 * @param {string} url
 *     URL of the script to add.
 * @param {Object=} opt_params
 *     Optional extra parameters to be added to the URL.  If one of the
 *     parameters is a function, that function will be used as the JSON-P
 *     callback function.
 * @returns {!Element}
 *     The script element that was added to the head.
 */
function addScript(url, opt_params) {
  // The context can be changed from this frame's window to a different
  // frame's window by using the call or apply function.
  var context = this, document = context.document;

  // Construct the entire URL.
  var urlHasParams = url.indexOf('?') +  1;
  if (opt_params) {
    var keys = Object.keys(opt_params), i = keys.length;
    while (i--) {
      var key = keys[i], value = opt_params[key];
      if (Object.prototype.toString.call(value) == '[object Function]') {
        var callback = value;

        // Add a function to the global namespace that will be used for the
        // JSON-P callback.
        value = '_';
        do {
          value += +new Date;
        } while (value in context);
        context[value] = function() {
          delete context[value];
          callback.apply(this, arguments);
        };
      }
      url += (urlHasParams++ ? '&' : '?')
        + encodeURIComponent(key) + '=' + encodeURIComponent(value);
    }
  }

  // Add the script to the HEAD.
  var script = document.createElement('script');
  script.src = url;
  script.type = 'text/JavaScript';
  document.getElementsByTagName('head')[0].appendChild(script);
  return script;
}

Now if you wanted to use this function for a JSON-P call you could do something like the following:


addScript('http://example.com/service?callback=myFunction');

This will only work assuming that you have myFunction defined in the global namespace. Now let’s say you want to make the same call but you want the callback to be an anonymous function. Here’s how you can do it:


addScript('http://example.com/service', {
  callback: function() {
    // Do the stuff you want here
  }
);

Of course the name of the callback parameter doesn’t have to be `callback`; it can be arbitrary. If you check out the code you will see that this works by actually temporarily adding a function to the global namespace. As soon as the temporary function is called it is removed from the global namespace.

As a final note it is important to mention is that if you will be passing opt_params to this function you will want to ensure that Object.keys is available in the environment in which your code will run (most browsers natively support this function). If this function isn’t assured to be defined in the environment, it would be a good idea to use code which emulates it. šŸ˜Ž

Categories: BlogJavaScript

1 Comment

Watch Anime & Cartoons Online for Free | Chris West's Blog · July 17, 2014 at 1:42 PM

[…] I’d also like to mention that the scripts added to handle the JSON-P calls are created by the function outlined here. […]

Leave a Reply

Your email address will not be published. Required fields are marked *