I cooked up a pattern to create and extend html elements using their prototype. This works like a charm in non-ie browsers. Example code can be found @jsbin1
The advantage of this pattern should be speed (the methods are in the elements prototype chain, so they are referenced once). You guessed right: IE no go. In IE < 8 the prototype of html elements is hidden/not accessible, so for every element you create, you have to reference the non standard methods again (leaving you with a lot of pointers if you use the pattern intensively). I have searched the web for solutions, but only found plex workarounds. Is there really no way to access a HTML elements prototype in IE?
1 Alas: the jsbin code is lost in clouds.
I cooked up a pattern to create and extend html elements using their prototype. This works like a charm in non-ie browsers. Example code can be found @jsbin1
The advantage of this pattern should be speed (the methods are in the elements prototype chain, so they are referenced once). You guessed right: IE no go. In IE < 8 the prototype of html elements is hidden/not accessible, so for every element you create, you have to reference the non standard methods again (leaving you with a lot of pointers if you use the pattern intensively). I have searched the web for solutions, but only found plex workarounds. Is there really no way to access a HTML elements prototype in IE?
1 Alas: the jsbin code is lost in clouds.
Share Improve this question edited Oct 24, 2023 at 8:17 KooiInc asked Feb 26, 2009 at 22:51 KooiIncKooiInc 123k32 gold badges145 silver badges181 bronze badges 6- Is the prototype of html elements available in IE8? If so, how is it accessed? – Helephant Commented Apr 13, 2009 at 13:00
- It is, as far as I understood. And it is accessed via the prototype (like document.getElementById('someelement').prototype). In the mean time I wrote a DOM-wrapper to be able to use leak free javascript. – KooiInc Commented Apr 13, 2009 at 20:34
-
@Helephant Yes, it's accessible. You can access, for example,
Element.prototype
and add methods to it. This is guaranteed by the latest version of the DOM Living Standard, which defines things likeElement
as WebIDL interfaces, which carries with it the explicit implication that they should be accessible in the global scope and their prototypes should be modifiable. – Mark Amery Commented Dec 20, 2014 at 0:16 -
1
Hey @KoolInc, your ment above from 2009 is erroneous (
document.getElementById('someelement').prototype
will throw aTypeError
; perhaps you could just delete it and then flag this ment of mine as obsolete for a mod to mop up? – Mark Amery Commented Dec 20, 2014 at 0:19 -
1
@KoolInc whoops, sorry, you're quite right that what you wrote will return undefined if the element exists (I was clearly testing on an element that wasn't actually present.) In any case it's still wrong since you haven't got the
.constructor
in what you originally wrote; constructors have theprototype
property, but instances do not. – Mark Amery Commented Dec 20, 2014 at 11:54
3 Answers
Reset to default 12No, nor is it guaranteed you can fiddle with DOM objects' prototypes in JavaScript in general. The DOM objects are not part of the ECMAScript spec; they may not be (and traditionally speaking aren't) native JavaScript Objects at all, in any browser.
This is why frameworks tend to have their own ‘container’ wrapper classes.
Also you cannot rely on ‘t.el.constructor’ even if they were native JS Objects. ‘constructor’ is not a standard property, isn't available in IE, and even in Mozilla doesn't do what you might think it does. Avoid.
Yes there really is no way to do this.
IE elements are based COM objects which actually don't allow arbitary members to be added to their interfaces (in COM, interfaces are a contract and should never change). Implementation of these interfaces cannot be extended by Javascript, the elements simply are not prototypal.
IE adds a special interface designed to work with Javascript to allow the addition of new members to a specific instance but you cannot add a new member to 'class' since there is no prototype to fiddle with.
The following, cut and pasted from the article HTMLElement doesnt work in IE. 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>
Try it Regards