2009-06-09 101 views
0

我创建了一个JavaScript类(使用Prototype),如果在指定的秒数内没有鼠标移动,它将把页面状态设置为空闲状态。当鼠标移动时,该类将通过向侦听器列表发送消息来“唤醒”页面。Javascript /原型范围混乱

我不明白的事情是,this.handlers是有效的在一个函数(setIdle),而不是另一个(setActive)。下面的注释代码说明我的问题:

var IM2 = Class.create({ 

handlers: null, 

initialize: function(callback, frequency) { 
    this.handlers = []; 
    Event.observe(document, "mousemove", this.sendActiveSignal); 
    Event.observe(document, "keypress", this.sendActiveSignal); 
    setInterval(this.sendIdleSignal.bind(this), 5000); 
}, 

addListener: function(h) { 
    console.log(this.handlers.size()); // it's 0 here, as expected 
    this.handlers.push(h); 
    console.log(this.handlers.size()); // it's 1 here, as expected 
}, 

sendIdleSignal: function(args) { 
    console.log("IDLE"); 
    this.handlers.each(function(i){ 
     i.setIdle(); 
    }) 
}, 

sendActiveSignal: function() { 
            // this.handlers is undefined here. Why? 
    this.handlers.each(function(r) { 
     r.setActive(); 
    }) 
} 

}); 
+0

你有在对象末尾添加一个额外的逗号,这可能会产生一些奇怪的错误,但我怀疑这是问题所在。如果在sendActive()内部执行console.log(this),会得到什么记录? – tj111 2009-06-09 14:49:34

回答

2

假设你的意思是它是有效的SendIdleSignal,它不是在SendActiveSignal有效...

你的事件侦听器也应该使用绑定,就像这样:

Event.observe(document, "mousemove", this.sendActiveSignal.bind(this)); 
Event.observe(document, "keypress", this.sendActiveSignal.bind(this)); 

另外,如果你使用的原型1.6或更高版本,可以使用

document.observe("mousemove", this.sendActiveSignal.bind(this)); 
document.observe("keypress", this.sendActiveSignal.bind(this)); 

此外,如果你想有一个通用的(框架无关)的方式来做到这一点,你可以定义你这样的功能:

sendActiveSignal: function() { 
    var that = this; 
    return function() { 
     that.handlers.each(function(r) { 
      r.setActive(); 
     }); 
    } 
} 

那么你的事件处理程序/可留的setInterval为

Event.observe(document, "keypress", this.sendActiveSignal); 
+0

准确地说,我错过了;谢谢! – yalestar 2009-06-09 14:55:34