bind a event function to a class but using removeEventListener and
removing his references allowing the garbagecollector to work correctly
As we all know when we create a class in javascript a normal function
returns the class object but events return the event object and the class
object gets lost
function class(a){
this.name=a;
document.addEventListener('click',this.click,false);
xhr.addEventListener('load',this.xhr,false);
this.normal()
}
class.prototype={
click:function(e){
//e=event,this=theDocument //can't access class
},
xhr:function(e){
//e=event,this=theXHR //can't access class
},
normal:function(e){
//e=null,this=class
}
}
Whats the best way to bind those events to our class?
by best way i mean no or just a tiny reference, the ability to remove the
events in a native way(removeEventListener) and to absolutely not create
memory leaks.
1.to remove an eventlistener you need to pass the function as a reference,
so addEventListener('click',function(){alert('something')},false) does not
work.
2.i read references like var that=this inside functions create leaks, true?.
Known ways
function class(a){
this.name=a;
var that=this;// reference
//simply reference the whole object as a variable.
var bindedClick=this.click.bind(this);//bind the click to the class
//(js 1.85)
//can i use removeEventListener('click',bindedClick,false) later?
//apply && call (js 1.3)
}
As i'm not shure if var that=this (as it is the whole object) creates
leaks, sometimes i minimize this by saving the info into an array and as
reference i use a id..
var class={};
var id='ID'+Date.now();
class[id].info={here i store all the info i need later text only}
//this will be stored also in a cookie / Localstorage to reuse later.
class[id].dom={here i store the dom references}
class[id].events{here i store the xhr events}//if needed
//this are Temp only
and to get the info i just pass the id by adding it to the event element
class[id].events.xhr.id=id;
class[id].events.xhr.onload=class.f
class.prototype.f=function(e){
//this.response,class[this.id]<- access everything.
this.removeEventListener('load',class.f,false);
delete class[this.id].events.xhr;
delete this.id
}
class[id].dom.id=id;
class[id].dom.onclick=class.f2
class.prototype.f2=function(e){
//class[e.target.id],class[this.id]<- access everything.
this.removeEventListener('click',class.f2,false);
delete class[this.id].dom;
delete this.id
}
As you can see in this example above i have acess to everything and the
reference is just a small string...
I store the dom because i define the dom references on load so i don't
have to call getElementById() everytime;
I store the events like XHR in the class as i want to be able to call
xhr.abort() from outside.. and also able to call removeEventListener.
I need to minimize the impact to the memory but at the other side i need
to control many elements that have multiple simultaneous events to control
the garbage collector "manually" by removing all events and references.
To make sure you understand that the problem is bigger thn it looks...:
it's a download manager for chrome. input field for download url:
1.xhr to get the fileinfo (size,name,acceptranges,mime)
2.store info in localstorage and cached array
2.create visual dom elements to show progress
(event:progress,click,mouseover..)
3.xhr request a chunk 0-1000(event:load)
4.onprogress display progress data (event:progress,error)
5.request filesystem(event:ok,error)
6.readfile/check file (event:ok,error)
7.request filewriter (event:ok,error)
8.append to file (events=ok,error)
9.on ok start again from 3. until file is finished
10.when finished i delete all the **references / events / extra info**
//this to help the garbage collector.
11.change the dom contents.
Every file has sooo many events every sec.
Which of these 3 is the best solution or are there any better solutions?
bind();//or call / apply
var that=this; //reference to the whole object
var id=uniqueid; // reference to the object's id
No comments:
Post a Comment