Category Archives: JavaScript

Inject Content into a new IFrame

In on-line ad delivery we utilize the <iframe> tag quite a lot. There are good reasons for serving ads in iframes. There are restrictions in communication between an iframe and its parent window when the two documents are served from different domains. This helps protect users as well as site publishers from malicious activity.

Iframes also provide advantages in the speed of delivery of an overall page. The parsing and display of an iframe’s content happens asynchronously to the rest of the parent window’s resources. This means that when an iframe is encountered during an initial page load it does not prevent the rest of the page from loading while the content of the iframe is loaded.

At AppNexus we’ve been developing some improved ad delivery mechanisms which leverage the advantages of iframes, in particular we’ve been leveraging the dynamic creation of iframes to serve ad content after some user interaction is applied. However, this has been a bit of an adventure as idiosyncrasies in how browsers handle the population of content in iframes and the rendering of their  documents.

Let me illustrate.

Here’s how we would use JavaScript to create a new iframe, give it some properties, set its initial source, and add it to the existing document.

var newIframe = document.createElement('iframe');
newIframe.width = '200';newIframe.height = '200';
newIframe.src = 'about:blank'; 
document.body.appendChild(newIframe);

I’ve set the src attribute to ‘about:blank’. This is generally a good practice because IE can behave strangely when an iframe is appended to the document without a source. Setting the src to about:blank makes this a “friendly” iframe which means that javascript code running inside the iframe can interact with the DOM and javascript defined in its parent window and vice versa. In other words, there are no restrictions on the communication and code execution between the iframe window and the parent window.

There are several different ways we can add content to our new iframe:

  • Change the src attribute to an external document URL
  • Use the DOM’s open(), write(), close() API to inject content
  • Use the javascript: URI scheme.

Here are examples of each approach.

I can set the src attribute to an external file:

newIframe.src = 'myIframeContent.html';

If this was my intent all along, then there’s no need to start with the ‘about:blank’ src. I can set this as the src directly.

This is not convenient if we don’t have access to the site’s initial domain, and we want to maintain the “friendly” nature of the iframe. In such a case we can use the DOM API to open the iframe’s document and dynamically write content into it.

var myContent = '<!DOCTYPE html>'
    + '<html><head><title>My dynamic document</head>'
    + '<body><p>Hello world</p></body></html>';

newIframe.contentWindow.document.open('text/html', 'replace');
newIframe.contentWindow.document.write(myContent);
newIframe.contentWindow.document.close();

First, I’d like to call out that the contentWindow isn’t created until we’ve added the iframe to the parent window’s DOM (which we did in the first code block above).

This approach is adequate to dynamically inject content into an iframe in most cases. However, if the content contains resources to external <script> resources you can run into problems in IE.

Look at this example in Chrome, and you will see an iframe populated with content using the approach above, and it includes a reference to an external script which provides content for the iframe.

However, if you look at the same page in IE, you will see a JavaScript error and no content is displayed in the iframe.

Here’s the code for the iframe:

var iframe = document.createElement('iframe');
var ctnr = document.getElementById('ctnr');
var content = '<!DOCTYPE html>'
 + '<head><title>Dynamic iframe</title>'
 + '<body><div id="innerCtnr"></div>'
 + '<script type="text/javascript" src="external.js"><\/script>'
 + '<script type="text/javascript">'
 + 'document.getElementById("innerCtnr").innerHTML = externalVar;'
 + '<\/script>' + '</body></html>';

ctnr.appendChild(iframe);

iframe.contentWindow.document.open('text/html', 'replace');
iframe.contentWindow.document.write(content);
iframe.contentWindow.document.close();

In external.js there is a variable defined which is referenced by the code which is being added in our document.write call. external.js is loaded asynchronous to the parsing of document.write(content), therefore at the time that we invoke this:

document.getElementById("innerCtnr").innerHTML = externalVar;

externalVar has not yet been defined and causes a ReferenceError.

To workaround this problem in IE we can make use of the javascript: URI scheme which makes bookmarklets and scriplets possible in all browsers. Instead of using document.open/write/close we use the following approach:

iframe.contentWindow.contents = content;
iframe.src = 'javascript:window["contents"]';

First, we assign the dynamic content to a variable on the iframe’s window object. Then we invoke it via the javascript: scheme. This not only renders the HTML properly, but loads and executes the scripts in the desired order.

Here’s an example using the javascript URI scheme.

Summary

Dynamic iframes are resourceful ways to add new content into a web page, but care and attention has to be paid as to how those iframes are injected with content to avoid errors caused by browser differences in loading and executing scripts added to those iframes.

Debugging JavaScript Events with Visual Event

I recently came across a handy tool for JavaScript debugging called Visual Event. Of course, modern JavaScript development would hardly even be possible without FireBug. And most advanced JS-based rich internet applications heavily leverage one of the major JavaScript framework libraries (e.g. YUI, jQuery, scriptaculous, etc.).

One of the limitations of Firebug in run-time debugging is it doesn’t have a good way to inform you of what methods are subscribed a DOM element’s events. If an element in the DOM is clicked on, moused over, value changed, etc. a JS event is fired. Any number of functions may be listening for that event and may get executed.

As applications become more complex, event subscriptions are spread across many files and those subscriptions can be conditional on particular logic flows. It becomes more and more difficult to determine what actions are  performed during certain events.

Event messaging is not consistent across browsers, and there is no W3C specified container that can be used to store and reference the document’s event listeners. As a result, each of the major JavaScript frameworks has its own mechanism for storing and executing event listeners.

Enter Visual Event. Written in jQuery, it’s compatible with YUI, MooTools, and of course jQuery. When run, it overlays the elements of your page with icons for each type of basic event associated with a DOM node that has listeners.

Here’s a basic DIV element with the text “Pull the trigger”:

On the left hand side is the basic DIV, on the right hand side is the visual event overlay. The DIV background color has been highlighted, and three icons have been displayed, each representing a listener and the type of icon indicates what event it is listening on.

This DIV has three listeners: one each for the click event, mouseover event, and mouseout event.

In these images there is also a red icon partially hidden, and this appears to be one of the jQuery listeners associated with Visual Event. This is unnecessary and adds noise to the tool, which has the potential to confuse the user.

If you click on any of the icons, an overlay is displayed that contains the source code for the listener:

overlay2

All in all, Visual Event is a very quick and handy JavaScript event debugging tool, and gives you information that you would have to gather manually through logging or alerts in standard debugging.

It’s not without its limitations however:

  • It only supports a sub-set of JavaScript libraries
  • It doesn’t work in IE
  • It doesn’t support custom events, but only handles the standard user interaction events supported by the browser
  • The listener display doesn’t indicate what file the function is located in, or it’s true line numbers

It’s important to note that this is a young tool, still classified as ‘beta’, and despite its limitations it can still come in extremely handy.

I wish I’d had it two years ago 🙂

Advanced JavaScript: Namespaces, Closures, Self-Invoking Functions, and much, much more…

In the past year that I’ve been working at Yahoo! I’ve found myself more in the role of UI Developer in web application development.

This involves developing the client-side display, the client behaviors, request and response handling with server-based actions which may interface with a series of back-end or 3rd party services. HTML and CSS are used for content mark-up and styling. JavaScript is used for manipulating the client data and display based on user interaction. AJAX is leveraged heavily to interact with services. A Java based action layer sits on the server and acts as the controller for request dispatching, and interfacing with various services.

Given JavaScript’s heavy usage in this structure, I’ve learned a lot about JS limitations and powers. For years I generally avoided doing any kind of development that relied heavily on JavaScript. It’s implementation across browsers was disparate, and errors were impossible to debug. Things have obviously improved drastically in the past few years.

An increased usage and reliance on JavaScript means it’s very important to write “enterprise-level” code in a language that doesn’t always assist you the way Java or Python do in this task. One of the things I’ve always disliked about JS is its confusing variable scoping.

This article will cover a series of concepts in advanced JS usage which can help developers avoid problems caused by poor scoping. These concepts include:

– Namespacing
– Self-Invoking functions
– Closures

First, let’s cover the concept of namespacing in JavaScript. Normally, you can define variables in JavaScript in two different methods:

myFirstVar = "some value";

var mySecondVar = "some other value";

In the case of myFirstVar, this is a global variable, no matter where you define this it will be available to all other JavaScript code in the page/screen where it occurs. Using this method to declare variables is extremely messy. With large applications you can easily eat up a lot of memory if you’re declaring global variables all over the place. Also, there’s a strong chance that during the execution of your code, you will encounter a collision where the same variable is getting used for different intended uses.

The second case: mySecondVar uses the “var” keyword to limit the scope to the current executing block of code, and all blocks of code within the current one. If mySecondVar was inside of a function or a conditional block, then it would be local to those blocks of code. In the case above, it’s essentially another global variable.

To avoid polluting the global scope, we’ll use an object structure with a semantic naming pattern to store all code that we need available on a global scope, but we’ll run much less risk of code collision and we’ll have a smaller memory footprint.

Let’s pretend we’re writing code for dgmlive.com. We’ll create a global JS object called DGM:

var DGM = {};

We can add functionality as children to this object. We could for instance create a series of objects that correspond to data entities that we use in dgmlive.com, and those objects would contain data and behavior specific to those entities. Examples include:

– DGM.Artist
– DGM.Recording
– DGM.util.DownloadConfirm
– DGM.widget.MediaPlayer

Now, we’re still going to have situations where we’ll want to declare variables that don’t naturally fit into a namespaced object structure. But we don’t want those variables to have a global scope. This is where self-invoking functions come in.

Normally in JavaScript, you define a function at some point in your script, and later invoke it. With a self-invoking function, it’s executed when the definition is parsed by the browser / client. Variables declared inside of a self-invoking function using the “var” keyword only have a scope local to that self-invoking function. Here’s what a self-invoking function looks like:

(function() {
    // All your JS code goes in here
})();

A functional example:

(function() {
    var myThirdVar = "Try to get at this outside this function";
})();

alert(myThirdVar); // undefined

Let’s take these concepts further and incorporate some object oriented programming principles to our JavaScript code that aren’t explicitly provided for with basic JavaScript.

Let’s build a basic version of the proposed DGM.Artist object. Here’s the code:

var DGM = {}; // only global property, the root of our namespace

(function () { // Self-invoking function

/**
* Creates a new artist object
*
* @param Object an initial configuration for this artist
* @constructor
*/
DGM.Artist = function(
/* Obj */		oConfig
) {

    // Define private members
    var _name = oConfig.name;
    var _givenName = "";
    var _surName = "";

    // Private logic method
    // A not-so-good way of getting first and last name from a single name
    var _splitName = function(name) {
        var names = name.split(" ");
        _givenName = names[0];
        _surName = names[1];
    };

        return { // publicly accessible API

            getName : function() {
                return _name;
            },

            setName : function(newName) {
                _splitName(newName);
                _name = newName;
            },

            getGivenName : function() {
                return _givenName;
            },

            getSurName : function() {
                return _surName;
            }

        };

    };

    var robertFrippConfig = {
        name : "Robert Fripp"
    };

    var newArtist = new DGM.Artist(robertFrippConfig);

    alert(newArtist.getName());
    alert(name);
    alert(givenName);

    newArtist.setName("Bobby Willcox");
    alert(newArtist.getName());
    alert(newArtist.name);
})();

Ok, there’s a lot there. Let’s walk through it a little at a time:

var DGM = {};

That’s the start of our namespace object. We’ll add children to it and avoid polluting the global namespace.

We then start a self-invoking function:

(function () {

It’s not really necessary to wrap the declaration of DGM.Artist in a self-invoking function, since this is just going to have the same scope as DGM, but it’s a nice touch. We do need the self-invoking function to contain the instantiation of DGM.Artist.

We declare DGM.Artist as a function, but we’re going to use it as an object constructor. It returns an object with a specific sub-set of functions that we want to make publicly accessible.

	DGM.Artist = function(
		/* Obj */		oConfig
	) {

        ...

        return { ... };

We create an instance of DGM.Artist using the new statement:

var newArtist = new DGM.Artist(robertFrippConfig);

Now let’s look closer at DGM.Artist. JavaScript doesn’t support different traditional OO member accessibility (i.e. public, protected, private). But we can use the “var” keyword and JS scoping to our advantage in this instance.

Variables declared with “var” inside of DGM.Artist constructor method are local to that method, and not accessible to JS outside of the method. However, the variables themselves persist inside each instance of that object. So, we can use traditional accessor methods (getters/setters) to manipulate those variables from outside. This behavior is called a closure.

This gives the programmer some power over how an object’s properties are manipulated during run-time. However, this shouldn’t be construed as any type of security measure to protect sensitive data.

So, getting back to the example, we set up a series of private variables which will contain data for each instance of DGM.Artist that we create:

                // Define private members
		var _name = oConfig.name;
		var _givenName = "";
		var _surName = "";

I’ve used the convention of putting an underscore in front of the member names. This does nothing other than visually indicate to the programmer that these are intended as private variables.

In the return block of the constructor method, I build an object which has a series of methods which can be used to manipulate these private variables after the instance is created:

return { // publicly accessible API

			getName : function() {
				return _name;
			},

			setName : function(newName) {
				_splitName(newName);
				_name = newName;
			},

			getGivenName : function() {
				return _givenName;
			}, 

			getSurName : function() {
				return _surName;
			}

		};

Take a look for a moment at the setName() method. This is used in the instance to change the name of the artist if necessary. Inside of setName() we call a private method _splitNames() defined in DGM.Artist constructor, which takes our name string and splits it into a given and a surname.

===

I hope this gives you some sense of how to avoid scoping problems in your JavaScript development, and also gives you some sense of how to use closures and object-oriented JavaScript to unleash some of the power that JavaScript has available.