JavaScript - HTMLElement In IE
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>
RSS ?
16 comments on this post
Has been this thing tested? it returns a bunch of errors both in IE and Mozilla.
Sirio,
The following, cut and pasted form the article examples works perfectly in IE and Firefox.
How to make DOMElement for Event Handler..??
ex) e.srcElement
This is pretty ass smart
This was a huge help in implementing the FBJS (Facebook JavaScript) support for Ringside Networks. Just wanted to say thanks!
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);
}
Actually you can find an unobtrusive inplementation of the HTMLElement at http://www.jslab.dk/epe.introduction.php
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!
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.
I had some problems with extending HTMLElements in IE. I tried various approaches unsuccessfully and after some research I found out that Prototype Javascript library has nice and browser compatible tools for extending HTML elements (http://www.prototypejs.org/learn/extensions)
–.–”
you should use:
_elem[name] = fn;
instead of that orrible eval(”_elem.” + name …);
Thanks from China!
This is exactly what I need!
You’re the man!
Very clever script, thanks heaps, helped me a ton.
2 Trackback(s)