JavaScript - HTMLElement In IE

JavaScript/Ajax Add comments

There are many things that irritate me about Internet Explorer like poor CSS support and the differences JScript brings to the table and the bugs that go along with that (memory leaks, etc, etc) but recently I found yet another reason to loath developing applications for IE. HTMLElement. Mozilla and Opera have given us the ability to prototype this object which greatly simplifies extending the document object model (DOM) however IE (also Safari) decided to keep this object hidden and untouchable. Why? Good question! Who knows what goes on in the minds of these “brilliant” programmers or, probably, more fairly, the project managers that oversee the development.

Anyways, compaining and speculation aside, I have come up with a method to work around these short comings and provide a way to extend the DOM. Enjoy!

JavaScript

var DOMElement =
{
	extend: function(name,fn)
	{
		if(!document.all)
			eval("HTMLElement.prototype." + name + " = fn");
		else
		{
			//
			//	IE doesn't allow access to HTMLElement
			//	so we need to override
			//	*document.createElement
			//	*document.getElementById
			//	*document.getElementsByTagName
			//

			//take a copy of
			//document.createElement
			var _createElement = document.createElement;

			//override document.createElement
			document.createElement = function(tag)
			{
				var _elem = _createElement(tag);
				eval("_elem." + name + " = fn");
				return _elem;
			}

			//take copy of
			//document.getElementById
			var _getElementById = document.getElementById;

			//override document.getElementById
			document.getElementById = function(id)
			{
				var _elem = _getElementById(id);
				eval("_elem." + name + " = fn");
				return _elem;
			}

			//take copy of
			//document.getElementsByTagName
			var _getElementsByTagName = document.getElementsByTagName;

			//override document.getElementsByTagName
			document.getElementsByTagName = function(tag)
			{
				var _arr = _getElementsByTagName(tag);
				for(var _elem=0;_elem<_arr.length;_elem++)
					eval("_arr[_elem]." + name + " = fn");
				return _arr;
			}
		}
	}
};

HTML

<html>
<head>
	<script type="text/javascript" src="DOMElement.js"></script>
	<script type="text/javascript">

		DOMElement.extend("foo",function(){alert('bar')});
		DOMElement.extend("about","DOMElement v0.1")
		DOMElement.extend("contents",function(){return this.innerHTML})
		var elem = document.createElement("div");
		elem.foo();

		onload = function()
		{
			var elem2 = document.getElementById("myDiv");
			alert(elem2.about);

			var divs = document.getElementsByTagName("div");
			for(var i=0;i<divs.length;i++)
				alert(divs[i].contents())
		}

	</script>
</head>
<body>

	<div id="myDiv">hi</div>
	<div id="div2">there</div>

</body>
</html>

Popularity: 13% [?]

If you liked this article consider subscribing to my free rss article feed to automatically get new articles in your feed reader.

11 Responses to “JavaScript - HTMLElement In IE”

  1. Sirio Says:

    Has been this thing tested? it returns a bunch of errors both in IE and Mozilla.

  2. Justin Says:

    Sirio,

    The following, cut and pasted form the article examples works perfectly in IE and Firefox.

    <html>
    <head>
    	<script type="text/javascript" src="DOMElement.js"></script>
    	<script type="text/javascript">
    
    		var DOMElement =
    		{
    			extend: function(name,fn)
    			{
    				if(!document.all)
    					eval("HTMLElement.prototype." + name + " = fn");
    				else
    				{
    					//
    					//	IE doesn't allow access to HTMLElement
    					//	so we need to override
    					//	*document.createElement
    					//	*document.getElementById
    					//	*document.getElementsByTagName
    					//
    
    					//take a copy of
    					//document.createElement
    					var _createElement = document.createElement;
    
    					//override document.createElement
    					document.createElement = function(tag)
    					{
    						var _elem = _createElement(tag);
    						eval("_elem." + name + " = fn");
    						return _elem;
    					}
    
    					//take copy of
    					//document.getElementById
    					var _getElementById = document.getElementById;
    
    					//override document.getElementById
    					document.getElementById = function(id)
    					{
    						var _elem = _getElementById(id);
    						eval("_elem." + name + " = fn");
    						return _elem;
    					}
    
    					//take copy of
    					//document.getElementsByTagName
    					var _getElementsByTagName = document.getElementsByTagName;
    
    					//override document.getElementsByTagName
    					document.getElementsByTagName = function(tag)
    					{
    						var _arr = _getElementsByTagName(tag);
    						for(var _elem=0;_elem<_arr.length;_elem++)
    							eval("_arr[_elem]." + name + " = fn");
    						return _arr;
    					}
    				}
    			}
    		};
    
    		DOMElement.extend("foo",function(){alert('bar')});
    		DOMElement.extend("about","DOMElement v0.1")
    		DOMElement.extend("contents",function(){return this.innerHTML})
    		var elem = document.createElement("div");
    		elem.foo();
    
    		onload = function()
    		{
    			var elem2 = document.getElementById("myDiv");
    			alert(elem2.about);
    
    			var divs = document.getElementsByTagName("div");
    			for(var i=0;i<divs.length;i++)
    				alert(divs[i].contents())
    		}
    
    	</script>
    </head>
    <body>
    
    	<div id="myDiv">hi</div>
    	<div id="div2">there</div>
    
    </body>
    </html>
  3. L.law.liet Says:

    How to make DOMElement for Event Handler..??
    ex) e.srcElement

  4. Olkenava » JavaScript - HTMLElement In IE Says:

    […] read more | digg story […]

  5. Bob Says:

    This is pretty ass smart

  6. Jason Says:

    This was a huge help in implementing the FBJS (Facebook JavaScript) support for Ringside Networks. Just wanted to say thanks!

  7. IE Object required error and other common coding mistakes : Lifescaler Says:

    […] HTMLElement is not accessible in IE, so in order to extend it, few hacks are necessary (first is to use Element.extend from prototype, or have a look at this: http://www.geekdaily.net/2007/06/18/javascript-htmlelement-in-ie/. […]

  8. David Murdoch Says:

    Thank you so much! I combined your code with a .htc to make sure that the “this” keyword worked always.


    HTML:
    <a href="#" onlick="this.remove();return false>Remove</a>

    CSS:
    *{behavior:common.htc}

    In the HTC:
    this.remove = function(){
    var el=(typeof this==='string')?document.getElementById(this):this;
    el.parentNode.removeChild(el);
    }

  9. Charlie Says:

    Actually you can find an unobtrusive inplementation of the HTMLElement at http://www.jslab.dk/epe.introduction.php

  10. Anthony Alexander Says:

    omg. i’d say about 75% of all ‘Ajax’ code written is to cover holes left by browsers and obvious neglected features. i wonder how long the standards guys are going to let the browser market be dominated by a plugin!

  11. Travis Uribe Says:

    The use of eval is completely unnecessary.
    If you used a for-in loop, an object literal as the function parameter, and hash notation, you could reduce this script to one third its size.

Leave a Reply

WP Theme & Icons by N.Design Studio
Entries RSS Login