Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I subclass a DOM-class?

I was wondering if I can create a subclass of HTMLDivElement. Like this.

MyDivElement.prototype.pickColor = function()
{
    return this.picked;
}
function MyDivElement()
{
    this = new HTMLDivElement();
    this.picked = 'unknowd';
}
alert(this.picked); // print: 'unkowd'

Is (something like) this possible? If not, what is the best way to achieve this?

like image 365
Tim Avatar asked Apr 17 '11 21:04

Tim


People also ask

What is a DOM class?

In JavaScript, DOM is actually a class that makes it really easy to define each element present within a web page so it can be modified later. Whenever a page is loaded in the browser, its document object is formed that is named as “document”.

How do you subclass in JavaScript?

Well, there are two methods which can be used to create a Javascript subclass, Pseudoclassical instantiation, and ES6. In pseudoclassical instantiation, creating a subclass requires the use of the 'function. prototype. call()' method and the 'Object.

Do subclasses inherit methods JavaScript?

When an object is a subclass of another object, it inherits the methods and properties of the 'parent' object and has access to those. Now let's discuss how pseudoclassical instantiation, subclassing and object inheritance works with ES6!


3 Answers

In browsers where __proto__ is exposed and mutable you can sub class DOM elements. It looks like this:

function CustomEl () {
    var el = document.createElement('div')
    el.__proto__ = CustomEl.prototype
    return el
}
CustomEl.prototype.__proto__ = HTMLDivElement.prototype

I also played with it in more detail on jsFiddle. Unfortunately though IE and Opera don't allow __proto__ access and have no plans to in the future as far as I know.

like image 176
Jake Avatar answered Sep 23 '22 10:09

Jake


new HTMLDivElement(); throws a TypError "Illegal constructor" in Chrome - so it's not possible.

Update: I've tested in other current browsers, and they throw various types of errors - but they all throw.


Actually, this would work:

function MyDivElement() {
    this.picked = 'unknowd';
}

MyDivElement.prototype = document.createElement('div');

var mydiv = new MyDivElement();

But I'm not sure how you could use this pattern...

like image 30
Šime Vidas Avatar answered Sep 23 '22 10:09

Šime Vidas


In some browsers, you can extend the prototype, in others, no. I'll let you guess the ones where you can't. :-) That's not really the same as extending a DOM element, but it does let you do a certain subset of the things for which you might want that facility. The thing is, DOM elements aren't really JavaScript entities; they're only simulacrums provided by the runtime system. (Maybe someday all the jsdom work will actually come to fruition.)

Well ok I'll tell you about the problematic browsers: IE doesn't like that at all. However others do. If you've ever looked at the Prototype library, you'll come across a manifestation of that fact all the time via nasty irritating IE-only bugs when you forget to Prototype-ize a DOM element reference.

(IE9 may be different, but I sort-of doubt it.)

This is the kind of thing that's dirt simple to test over at jsfiddle.

like image 29
Pointy Avatar answered Sep 20 '22 10:09

Pointy