我已经编写了这个简单的类来创建一个带有消息的div元素,该消息应该在给定时间后消失。这很好用,但是当用这个创建多个消息时,hide和destroy函数将仅适用于最后创建的消息。
这是我的班级:
function message(text, duration){
var self = this;
function init(){
this.obj = document.createElement("div");
this.obj.setAttribute("class", "message");
this.obj.appendChild(document.createTextNode(text));
document.body.appendChild(this.obj);
setTimeout(function(){self.display.call(this);}, 20);
setTimeout(function(){self.hide.call(this);}, duration);
setTimeout(function(){self.destroy.call(this);}, duration+1000);
}
this.display = function(){
this.obj.setAttribute("class", "message display");
}
this.hide = function(){
this.obj.setAttribute("class", "message gone");
}
this.destroy = function(){
document.body.removeChild(this.obj);
}
init();
}
这有效:
new message("This will be removed in 5 seconds.", 5000);
这不应该有效:
new message("This will not be shown", 2000);
new message("This will be removed after 2 seconds", 5000);
可能存在一些参考错误,但我无法发现任何错误。
答案 0 :(得分:2)
你非常接近一个有效的解决方案。我在这里修改了代码:http://jsfiddle.net/GTpKV/
您(正确)对此self
进行了引用,但在您的代码中仍使用this
(this
在使用内部函数时丢失,并且您还直接调用init,意味着this
在这种情况下会引用window
。如果你使用this.init()
它会在对象上正确创建引用,但是超时会使事情搞乱。最安全的方式(我已采取)是简单地用this
替换所有出现的self
。另一个想法是分析上下文何时是正确的,何时不是。但是,由于您已经在self
中拥有了正确绑定的上下文,因此您也可以使用它。以下是JSFiddle链接中的更正代码:
function message(text, duration){
var self = this;
function init(){
self.obj = document.createElement("div");
self.obj.setAttribute("class", "message");
self.obj.appendChild(document.createTextNode(text));
document.body.appendChild(self.obj);
setTimeout(function(){self.display();}, 20);
setTimeout(function(){self.hide();}, duration);
setTimeout(function(){self.destroy();}, duration+1000);
}
this.display = function(){
self.obj.setAttribute("class", "message display");
}
this.hide = function(){
self.obj.setAttribute("class", "message gone");
}
this.destroy = function(){
document.body.removeChild(self.obj);
}
init();
}
new message("This will not be shown", 2000);
new message("This will be removed in 5 seconds.", 5000);
答案 1 :(得分:1)
我相信这些this
会成为window
:
setTimeout(function(){self.display.call(this);}, 20);
setTimeout(function(){self.hide.call(this);}, duration);
setTimeout(function(){self.destroy.call(this);}, duration+1000);
请尝试:
setTimeout(function(){self.display()}, 20);
setTimeout(function(){self.hide()}, duration);
setTimeout(function(){self.destroy()}, duration+1000);
另外,为什么不在代码的其余部分使用self
:
function init(){
self.obj = document.createElement("div");
self.obj.setAttribute("class", "message");
self.obj.appendChild(document.createTextNode(text));
document.body.appendChild(self.obj);
setTimeout(function(){self.display()}, 20);
setTimeout(function(){self.hide()}, duration);
setTimeout(function(){self.destroy()}, duration+1000);
}
this.display = function(){
self.obj.setAttribute("class", "message display");
}
this.hide = function(){
self.obj.setAttribute("class", "message gone");
}
this.destroy = function(){
document.body.removeChild(self.obj);
}
(我想我得到了所有这些......如果我也错过了一个地方,请告诉我)
答案 2 :(得分:0)
也许你可以尝试这个解决方案。摆脱init
功能并将this
内的setTimeout
更改为self
,并取消不必要的call
。
的Javascript
function message(text, duration) {
var self = this;
this.display = function () {
this.obj.setAttribute("class", "message display");
}
this.hide = function () {
this.obj.setAttribute("class", "message gone");
}
this.destroy = function () {
document.body.removeChild(this.obj);
}
this.obj = document.createElement("div");
this.obj.setAttribute("class", "message");
this.obj.appendChild(document.createTextNode(text));
document.body.appendChild(this.obj);
setTimeout(function () {
self.display(self);
}, 20);
setTimeout(function () {
self.hide(self);
}, duration);
setTimeout(function () {
self.destroy(self);
}, duration + 1000);
}
new message("This will not be shown", 2000);
new message("This will be removed after 2 seconds", 5000);
上