Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'document.id' documentation and the DOM

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.

like image 214
Manaus Avatar asked Oct 20 '22 05:10

Manaus


1 Answers

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.

like image 85
Dimitar Christoff Avatar answered Oct 30 '22 21:10

Dimitar Christoff