Namespaces, duplicate functions and more IE nightmaresI was working on some code the other night which belonged to a site similar to my own in which numerous scripts and 
"semi frameworks" were being included. By 
semi framework I mean an 
add-on script that includes numerous functions that will almost certainly be replicated elsewhere in the site 
(DOM manipulation, event handlers etc).
The code involved using an iframe and then 
running an onload event as soon as the content had loaded so that I could 
resize the iframe to the correct dimensions for the content within. I had a bit of code like this:
addEvent(document.getElementById('myIframe'),"load",resizeIframe);
// resize iframe content onload
function resizeIframe(){
var dc = S.getIframeDoc(this); // return iframe document
var h = dc.body.scrollHeight; // get height of document within iframe
this.height = h+30+"px"; // set height of iframe+30 to ensure no scrollbars
}
As you can see the function 
resizeIframe which is called when the iframe loads uses the 
this keyword to reference itself rather than getting a reference to itself using 
getElementById which is fine as long as you are using a proper browser that supports the 
DOM 2 event model. However as 
IE does not support this model it has a problem with the
 this keyword in that it references the 
global window object instead of the iframe.
However this is a well known problem and many a solution has been created to get round this issue in 
Internet Explorer. On the site in question I use the following function which as you can see handles 
DOM 2, IE's event model and the older DOM 0 event model. It also correctly handles the 
this keyword problem by storing a reference in the DOM to the function. Read up on 
PPKs event handler content for more details.addEvent = function( obj, type, fn, cp )
{   
if(obj){
 if(obj.addEventListener){
  cp = cp || false;
  obj.addEventListener( type, fn, cp );
 }else if ( obj.attachEvent ) {   
  obj[type+fn] = function(){fn.call(obj,window.event);}
  obj.attachEvent( 'on'+type, obj[type+fn] );
 }else{
  var ev='on'+type;
  var oldevent = obj[ev];
  if (typeof oldevent != 'function'){  
   obj[ev]=fn;
  }else{  
   obj[ev] = function(){ oldevent();fn();}
  }
 }
}
}
However when testing the site in 
Internet Explorer I was getting errors when trying to reference the 
contentWindow.document in my resizeIframe function saying its 
null or not an object.The reason being that the 
this keyword was referencing the window object and there is no such object property on the 
global object.I spent some time scratching my head and looking over the function at hand and then when I put some 
debug code into the 
addEvent function and noticed it not appearing it at all the problem suddenly made sense. After a quick search through the 
other JS files being included on the page in question I came across the following function in a script called 
sorttable.js used for sorting table contents.
function addEvent(elm, evType, fn, useCapture)
{
if (elm.addEventListener){
 elm.addEventListener(evType, fn, useCapture);
 return true;
}else if (elm.attachEvent){
 var r = elm.attachEvent("on"+evType, fn);
 return r;
} else {
 var o = elm[evType];
 if(typeof(o)=="function"){
  elm[evType] = function(){o();fn();}
 }else{
  elm[evType] = function(){fn();};
 }
}
}
As you can see its another 
addEvent function and one that doesn't handle the 
this keyword problem in IE.As this script was being included after my own file it was 
overwriting the previous addEvent function and therefore was the cause of the error.
Now this self taught lesson reminded me of a recent post I wrote about the amount of 
duplicate frameworks and semi frameworks being included on websites at the moment. I reckon that on this page in question there was at least 
5 different places where a function to add an event listener was being declared:
-My own 
addEvent function in my standard library 
strictly.js-The 
addEvent function in the 
sorttable.js script
-
JQueries own methods to bind events - different names but doing the same action.
-
GooglesAJAX library would surely have its own event handlers.
-
AddThis add-on also had a similar event handler.
Therefore 5 scripts all doing the same thing. I explain it more in my earlier post:
http://blog.strictly-software.com/2009/08/large-number-of-duplicate-frameworks.htmlwhere I discuss the possibility of a
 standard global API for implementing these sort of functions that are nearly always replicated in 
add-on scripts. This would allow developers to choose the 
framework to handle this type of work and 
add-on developers wouldn't have to worry about implementing duplicate code.
Another solution would be if the 
add-ons would separate their code out into 2 files. The first file would contain the 
core functionality and then the other file would contain the functions that
 could/should be handled by the main framework used by the site.
This would allow the site developer to 
reduce the size of their codebase as they could choose to remove the 2nd file (if they wished) and allow their
 primary framework to handle the work that a lot of 
add-ons duplicate such as 
DOM manipulation and event handling.Obviously this works only if the 
add-on is using the same naming convention as the many frameworks and if the 
frameworks don't even share the same 
naming convention then this would seem hard to achieve. However we could always use 
wrapper functions or aliases to 
point the add-on functions at the desired framework objects e.g for our 
addEvent function:// addEvent used by this script
// params supplied
// obj = object, type = event, fn = function
// set alias so that add-on can use sites primary framework e.g jQuery/Prototype
A = addEvent = function(obj,type,fn){
$(obj).bind(type,fn);
}
Which allows the add-on to 
add event listeners with a call to 
A or addEvent with either call just being a 
pointer to the frameworks bind method. The add-on provider could either provide these alias wrappers themselves or just 
outline the interface required and allow the 
developer to implement the code.And of course if the 
user of the add-on didn't use a framework then they could choose to utilise the 2nd files functions as is even if they were duplicated in 5 other places.
This is all just ideas at the moment but I am 
developing an add-on at the moment that is going to try this approach.
Why Namespaces are such a good ideaAnother solution to the problem of 
duplicated functions is to always use 
namespaces to define your functions and objects so that there is little if no chance of two functions having the same name. The writer of the 
sorttable.js file didn't use a namespace to define his functions but if I had of defined my own 
addEvent function like so instead:
Strictly.addEvent = function(obj, type, fn){ ...
// call like so
Strictly.addEvent(document.getElementById('myIframe'),"load",Strictly.resizeIframe);
I would not have had any problem working out why my function wasn't working as expected unless one of the other 
add-ons also had used the 
namespace Strictly!
Obviously 
using namepaces may solve the problem of functions being overwritten but it doesn't solve the issue of
 duplicated functionality.Object Comparisons in Internet ExplorerNow whilst I was scratching my head in relation to the this problem I looked into creating a little test function that would tell me whether 
this equated to the global object or not as I was going a bit offtrack and of course a simple 
this === window should do the trick. However whilst looking into the different methods of 
object comparision I came across some of the differences between 
browsers of how 
object comparison is carried out. I don't know why I thought 
IE wouldn't be the odd one out as it always is but you might find the results interesting or you may not.
Make sure you view the test page in 
IE and a standards compliant browser like Firefox for comparison so that you see what I mean:
www.strictly-software.com/thistest.htmwindow === window.top is 
true in Firefox and 
false in IE.
window == document is 
false in Firefox and 
true in IE.
var _w=window;
_w === window.top is 
true in Firefox and 
false in IE.
When 
this relates the the 
global window object:
this === window.top is 
true in Firefox and 
false in IE
this === self is 
true in Firefox and 
false in IE
This may all be old news as far as 
JS developers are concerned but it was news to me so I thought I would post the link anyway.