In the Mootools docs, regarding Element, I cannot catch the semantic area of the document
element, for which I cannot find any reference in the Mootools Api. Is it just DOM Api?
For example $
accepts three parameters, the first of them is element
. How do I define an element?
Further, the docs offer some advice: document.getElementById(‘foo’)
, document.id(‘foo’)
, $(‘foo’)
. So I understand document
is a pretty important part of Mootools, but I do not understand where it overlaps to the classic DOM API, how far it is extended and so on.
So, MooTools has the concept of Types. Types are hashes built on top of either custom objects or by extending prototypes of Natives (Array
, Element
, String
, Function
, Number
, to name a few) or appending methods to Natives (Date
, Object
).
The Element Type (http://mootools.net/core/docs/1.5.1/Element/Element) is the abstraction around HTMLElement
as well as sub types like HTMLInputElement
, all part of the DOM interface.
document
itself is inheriting from Element
to a degree - prototype methods available on any HTMLElement will be available to call on document
as well, though they may not always be applicable. For example, addEvent
will work and makes sense but tween
or show
etc won't.
Let's assume you mean
document.id
Extending natives is considered harmful because it can result in unwanted side effects. Additionally, not every browser exposes the HTMLElement
prototype for modification equally. Whereas in evergreen browsers (read, not IE 8 and lower), HTMLElement
is OK to change, in IE6-7 it was not (read-only) and in IE8, it only extends some types of elements whereas others have no link to the augmented prototype chain.
So, imagine you have this:
<div id="foo">foo</div>
and a corresponding object:
var foo = document.getElementById('foo');
Since the constructor of foo is Element
and the prototype of foo is Element.prototype
, if you called foo.addEvent
it will look up the chain, reach the Element.prototype.addEvent
method and call it.
But because of IE6,7,8, the above may not work well or at all - MooTools devs chose a radical way of beating this issue by doing something simple: shortening the scope of the property lookup chain in these browsers.
This is done by actually setting a reference on the foo
object itself pointing to all the methods and properties on the Element.prototype
object.
you can think of doing it this way:
foo.addEvent = Element.prototype.addEvent.bind(foo);
so even if foo does not have access to the proto chain, it will still be able to call the method.
This so called 'extending' takes place the first time MooTools passes an element object.
So, in our case if in IE, you'd do:
foo = $(foo); // or document.id(foo);
Upon passing the element, it gets decorated with the references of the methods that you can now call
here's a better example:
var foo = document.getElementById('foo'), bar;
console.log(foo.hasOwnProperty('addEvent')); // false in all browsers
try {
foo.addEvent('click', bar = function(){});
}
catch(e){
console.log(e);
foo = $(foo);
foo.addEvent('click', bar = function(){});
console.log(foo.hasOwnProperty('addEvent')); // true in IE6,7,8
}
// by now it's already extended, so we can safely call it.
foo.removeEvent('click', bar);
further more: not only does document.id
(which $
will alias to) enable proto methods use, it also sets up a Slick.uuid
to recognise the element, which is then used to enable Element Storage
via the data API (Element.prototype.store
/retrieve
/eliminate
). This way, the Storage object has a unique key that maps to exactly one element in the DOM so you can stick stuff on there - it's the same implementation as jQuery's .data
API.
FINALLY, document.getElementById
is just JS api that gets you an element object. that's untouched by MooTools.
TL;DR; document.id(mixed)
prepares elements for use with MooTools in a cross browser way and sets up storage.
Passing an element extends and returns the element object. Passing a string finds an element by ID if possible, then extends result and returns object.
You can also use new Element()
constructor to create an element on document.createElement
- as well as any HTMLElement you may have gotten from any QSA or DOM API.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With