简体   繁体   English

Javascript / Prototype范围混淆

[英]Javascript/Prototype scope confusion

I'm creating a JavaScript class (using Prototype) that will set the page state to idle if there's no mouse movement within a specified number of seconds. 我正在创建一个JavaScript类(使用Prototype),如果在指定的秒数内没有鼠标移动,它将把页面状态设置为空闲。 When the mouse moves, the class will "wake up" the page by sending a message to a list of listeners. 当鼠标移动时,该类将通过向侦听器列表发送消息来“唤醒”页面。

The thing I don't understand is that this.handlers is valid in one function ( setIdle ), but not another ( setActive ). 我不明白的是, this.handlers在一个函数( setIdle )中有效,而在另一个函数( setActive )中无效。 The annotated code below illustrates my problem: 以下带注释的代码说明了我的问题:

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();
    })
}

});

Assuming you mean it's valid in SendIdleSignal and it's not valid in SendActiveSignal... 假设您的意思是在SendIdleSignal中有效,而在SendActiveSignal中无效...

Your event listeners should also use bind, like this: 您的事件监听器还应该使用bind,如下所示:

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

Also, if you're using prototype 1.6 or higher, you can use 另外,如果您使用的是原型1.6或更高版本,则可以使用

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

Additionally, if you want a generic (framework agnostic) way to do this, you could define your functions like this: 此外,如果您希望使用通用(与框架无关)的方法来执行此操作,则可以这样定义函数:

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

then your event handlers/setInterval could be left as 那么您的事件处理程序/ setInterval可以保留为

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM