Element wrappers are coming. We are going to see more frameworks using wrappers for JavaScript DOM Elements.
Sam Stephenson created the Prototype JavaScript Framework and pioneered extending native DOM Elements. For browsers that support it, Prototype extends HTMLElement.prototype. But Prototype 2.0 will not extend DOM Elements any more.
Extending DOM Elements has many negative side effects and I would say is even considered harmful. In that Ajaxian article, you can find a link to Kangax’s post that explains what is wrong with extending the DOM.
So here’s some ideas for Element wrappers that I’ve toyed around with myself. I’ll call the Element wrapper class WrappedEl
.
The $
type function
You can choose any name, but in Prototype and MooTools, the $
function takes an ID or element and returns an extended Element.
$
is a shortcut forWrappedEl.getInstance()
.$
accepts string IDs, html strings, DOM Elements andWrappedEl
instances.$
should ensure that only one wrapper is created per Element. You can store a reference to the wrapper in an expando property or in a hash ofid => WrappedEl
pairs.
The WrappedEl
Class
This is where the magic happens.
WrappedEl
should provide functions to manipulate every native property or function. Some examples:WrappedEl#update()
to setinnerHTML
,WrappedEl#getAttribute()
to provide a cross-browser method that mirrorsHTMLElement#getAttribute()
,WrappedEl#setProperty()
to set properties directly.- Should provide a way to add methods. Would be nice if it provides a way to add methods for a certain tag. In that case it is probably best to use subclasses; e.g.
WrappedEl
is a parent ofWrappedElTextarea
. It even makes sense to add new methods by default to some tags; e.g. add aWrappedElTextarea#value()
to get and set thevalue
property of a textarea. - Should feel the same as DOM Element extension. If current scripts avoid using properties such as
value
andinnerHTML
theWrappedEl
could even be compatible with an API that extends DOM Elements. - It is nice if the
WrappedEl
class provides generics. In other words the ability to call all the instance methods statically by passing the element as the first argument.
Collections
Once your WrappedEl
is ready, you are not many lines away from adding jQuery-like API. So you might as well code it!
- Create a collection class–called, say,
WrappedElList
. - Define a method for every
WrappedEl
method. - Chainable methods like setters should return the
WrappedElList
object. - Methods that return an HTML NodeList should return a concatenated collection of
WrappedEl
objects in anArray
–or even better–in aWrappedElList
object. - Some methods such as
getAttribute
should return the result for the firstWrappedEl
in the collection. - The method to add methods to
WrappedEl
may even be smart enough to automatically add methods toWrappedElList
.
I’d love to hear your ideas or suggestions in the comment section!
Happy Wrapping!