javascript – 将事件函数绑定到类但使用removeEventListener并删除其引用,以允许garbagecollector正常工作
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript – 将事件函数绑定到类但使用removeEventListener并删除其引用,以允许garbagecollector正常工作,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5591字,纯文字阅读大概需要8分钟。
内容图文
![javascript – 将事件函数绑定到类但使用removeEventListener并删除其引用,以允许garbagecollector正常工作](/upload/InfoBanner/zyjiaocheng/744/73e09dd59f8c40d3a0bd2af0a63edadb.jpg)
众所周知,当我们在javascript中创建一个类时,普通函数返回类对象但事件返回事件对象而类对象丢失
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
}
}
什么是将这些事件绑定到我们班级的最佳方式?
通过最好的方式,我的意思是没有或只是一个小参考,能够以本机方式删除事件(removeEventListener),绝对不会创建内存泄漏.
1.删??除一个eventlistener你需要将该函数作为引用传递,因此addEventListener(‘click’,function(){alert(‘something’)},false)不起作用.
2.i读取类似var的引用=这里面的函数创建泄漏,是吗?
已知方式
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)
}
因为我不是shure如果var = this(因为它是整个对象)会产生泄漏,有时我通过将信息保存到数组中来最小化这个并且作为参考我使用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
并获取信息我只是通过将其添加到event元素来传递id
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
}
正如您在上面的示例中所看到的,我对所有内容都有所了解,而且引用只是一个小字符串……
我存储dom,因为我在加载时定义dom引用,所以我不必每次都调用getElementById();
我将类似XHR的事件存储在类中,因为我希望能够从外部调用xhr.abort()并且还能够调用removeEventListener.
我需要最小化对内存的影响,但在另一方面,我需要控制许多具有多个同时事件的元素,通过删除所有事件和引用来“手动”控制垃圾收集器.
为了确保您了解问题更大,它看起来……:
它是chrome的下载管理器.下载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.
每个文件每秒都有很多事件.
这三种中哪一种是最佳解决方案还是有更好的解决方案?
bind();//or call / apply
var that=this; //reference to the whole object
var id=uniqueid; // reference to the object's id
根据答案:
(function(W){
var D,dls=[];
function init(){
D=W.document;
dls.push(new dl('url1'));
dls.push(new dl('url2'));
}
function dl(a){
this.MyUrl=a;
var that=this;
var btn=D.createElement('button');
btn.addEventListener('click',this.clc,false);
D.body.appendChild(btn);
}
dl.prototype={
clc:function(e){
console.log(that)
}
}
W.addEventListener('load',init,false);
})(window)
var that =这不起作用.
这工作…但我需要很多检查,如果和执行多个功能swich.
(function(W){
var D,dls=[];
function init(){
D=W.document;
dls.push(new dl('url1'));
dls.push(new dl('url2'));
}
function dl(a){
this.MyUrl=a;
this.btn=D.createElement('button');
btn.addEventListener('click',this,false);
D.body.appendChild(btn);
}
dl.prototype={
handleEvent:function(e){
e.target.removeEventListener('click',this,false);//does this the work?
return this.clc(e);
},
clc:function(e){
console.log(this,e)
}
}
W.addEventListener('load',init,false);
})(window)
BIND:
(function(W){
var D,dls=[];
function init(){
D=W.document;
dls.push(new dl('url1'));
dls.push(new dl('url2'));
}
function dl(a){
this.MyUrl=a;
this.clcB=this.clc.bind(this);
this.btn=D.createElement('button');
this.btn.addEventListener('click',this.clcB,false);
D.body.appendChild(this.btn);
}
dl.prototype={
clc:function(e){
e.target.removeEventListener('click',this.clcB,false);//does this the work?
delete this.clcB;
console.log(this)
}
}
W.addEventListener('load',init,false);
})(window)
解决方法:
更好的解决方案是让您的“类”实现EventListener接口.
您可以通过向MyClass.prototype添加handleEvent方法来完成此操作.这允许您将对象直接传递给.addEventListener(),而不是传递处理程序.
发生事件时,将调用handleEvent()方法,并将您的对象作为此值.这允许您访问对象的所有属性/方法.
function MyClass(a) {
this.name = a;
// pass the object instead of a function
document.addEventListener('click', this, false);
xhr.addEventListener('load', this, false); // where did `xhr` come from?
this.normal()
}
MyClass.prototype = {
// Implement the interface
handleEvent: function(e) {
// `this` is your object
// verify that there's a handler for the event type, and invoke it
return this[e.type] && this[e.type](e);
},
click: function (e) {
// `this` is your object
},
load: function (e) {
// `this` is your object
},
normal: function (e) {
// `this` is your object
}
}
请注意,我更改了要加载的xhr方法的名称.这样可以更轻松地根据事件类型调用正确的方法.
然后,当需要调用.removeEventListener()时,只需从元素中执行,但再次传递对象而不是处理程序.
内容总结
以上是互联网集市为您收集整理的javascript – 将事件函数绑定到类但使用removeEventListener并删除其引用,以允许garbagecollector正常工作全部内容,希望文章能够帮你解决javascript – 将事件函数绑定到类但使用removeEventListener并删除其引用,以允许garbagecollector正常工作所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。