Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is $(document.body) and document.body the same? Cleaning garbage and binding in class? - MooTools 1.3

I am building a MooTools class and I have this in my initialize function:

this.css = null;

window.addEvent('domready', function(){

    this.document = $(document);
    this.body = $(document.body);
    this.head = $(document.head);

}.bind(this));

Ok and now to the questions ... Should I declare this.css = null or any other empty variable in the init:

this.css = null; // Maybe this.css = '' - empty string?

Next thing is about window and document ... Should I put it into $() or not because it works both way, so I just want to know which way is preferred? So to summarize:

window.addEvent() // or should I use $(window).addEvent()
this.document = $(document) // or this.document = document
this.body = $(document.body) // or this.body = document.body

I stored these values into object to avoid multiple DOM queries, is this ok? Or would it be better to call $(selector) / $$(selector) every time?

Two more things left ... About binding ... Is it ok to use .bind(this) every time or would it be better to use .bind(this.myDiv) and use it inside function as eg.: this.setStyle(...); instead of this.myDiv.setStyle(...)

(function(){
  this.setStyle('overflow-y', 'visible');
 }.bind(this.body)).delay(100);

or

(function(){
  this.body.setStyle('overflow-y', 'visible');
 }.bind(this)).delay(100);

And the last thing is about garbage collection ... Do I have to garbage myself and how to do it (as far as I know MooTools does it on its own on unload). The confusing part is that I found function in MT docs:

myElement.destroy();

They say: Empties an Element of all its children, removes and garbages the Element. Useful to clear memory before the pageUnload.

So I have to garbage on my own? How to do that? When to use .destroy()? I am working on a huge project and I notice that IE gets slow over multiple executions of the script (so how to handle that? probably some cleaning needed, memory leaks?).

like image 936
jzvelc Avatar asked Jan 21 '11 01:01

jzvelc


1 Answers

pff, this is a bit long.

first, initial variables. this.css = null... the only time i'd set 'empty' variables are: typecast; when it's a property of an object i may reference and don't want undefined; when it's a string i will concatenate with or a number i will incre/decrement; null is not really useful at this point.

a common / good practice when writing a mootools class is to use the Options class as a mixin. this allows you to set default options object with your default settings that can be overridden upon instantiation. similarly, Object.merge({ var: val}, useroptions); can override a default val if supplied.

now, iirc, there are times when you'd have to use $(document.body) and it's not because document.body does not work, it's because applying $() also applies Element prototypes in IE (since Element prototype is not extended there, the methods are applied to the elements directly instead, which happens when you $ them). Also, $ assigns an internal UID of the target element and allows for element storage to be used for that element. I don't see a point to using $(document) or $(window) - they are 'extended' as much as needed by default. In any case, even in IE, you only need to $(something) the one time and can continue using it as just 'something' afterwards. check my document.getElementById("foo").method() example - you can just run $("foo"); on it's own and then try document.getElementById("foo").method() again - it will work in IE too.

window.addEvent(); // is fine. 
document.body.adopt(new Element("div")); // not fine in IE.
new Element("div").inject(document.body); // fine.

and on their own:

$(document.body).adopt(new Element("div")); // fine.
document.body.adopt(new Element("span")); // now fine, after first $.

see this in ie8: http://www.jsfiddle.net/AePzD/1/ - first attempt to set the background fails but the second one works. subsequently, document.body.methods() calls are going to work fine.

http://www.jsfiddle.net/AePzD/2/ - this shows how the element (which $ also returns) can have methods in webkit/mozilla and not in trident. however, replace that with $("foo") and it will start working. rule of thumb: $ elements you don't dynamically create before applying methods to them.

storing selectors can be a good performance practice, for sure. but it can also fill your scope chain with many variables so be careful. if you will use a selector two or more times, it's good to cache it. failing to do so is not a drama, selector engines like sizzle and slick are so fast these days it does not matter (unless you are animating at the time and it impacts your FPS).

as for binding, whichever way you like.

keep in mind delay has a second argument, BIND:

(function(){
      this.setStyle('background', 'blue');
 }).delay(100, $("foo"));

so do quite a few functions. this particular bind is not very useful but in a class, you may want to do

(function(){
      this.element.setStyle('background', 'blue');
      this.someMethod();
 }).delay(100, this));

GC. mootools does it's own GC, sure. however, .destroy is a very good practice, imo. if you don't need something in the DOM, use element.dispose(). if you won't attach it to the DOM again, use .destroy() - removes all child nodes and cleans up. more memory \o/

advice on IE... dodgy. you can use drip if you can to trace memory leaks, there are things like dynatrace that can be very good in profiling. in terms of practices... make sure you don't use inline js, you always clean up what you don't need (events, elements) and generally, be careful, esp when you are stacking up events and dealing with ajax (bring new elements that need events - consider event delegation instead...). use fewer dom nodes - also helps...

like image 152
Dimitar Christoff Avatar answered Oct 12 '22 01:10

Dimitar Christoff