如何在javascript中运行对象的onEvent方法?

4

我刚开始学习JavaScript,我的知识中缺少一些重要的东西。希望你能帮助我填补这个空白。

我正在尝试运行的脚本应该计算文本字段中的字符,并更新一个段落,告诉用户他们已经输入了多少个字符。我有一个名为charCounter的对象。sourceId是要计算字符数的文本区域的id。statusId是每次按键时要更新的段落的id。

function charCounter(sourceId, statusId) {
    this.sourceId = sourceId;
    this.statusId = statusId;
    this.count = 0;
}

有一种方法叫做updateAll,它可以更新字符的数量并更新段落。

charCounter.prototype.updateAll = function() {
    //get the character count;
    //change the paragraph;
}

我有一个启动函数,当窗口加载时会被调用。

function start() {
    //This is the problem
    document.getElementbyId('mytextfield').onkeydown = myCounter.updateAll;
    document.getElementbyId('mytextfield').onkeyup = myCounter.updateAll;
}

myCounter = new charCounter("mytextfield","charcount");
window.onload = start;

上面的代码有问题。为什么在事件触发时我不能调用myCounter.updateAll方法?这真的让我很困惑。我知道如果你调用一个类似这样的方法likeThis(),你会从函数中得到一个值。如果你调用它likeThis,你得到的是一个指向函数的指针。我将我的事件指向了一个函数。我也尝试直接调用该函数,它能正常工作,但在事件触发时却无法工作。
我错过了什么吗?
感谢所有回答。下面是三种不同的实现方式。

实现方式1

function CharCounter(sourceId, statusId) {
    this.sourceId = sourceId;
    this.statusId = statusId;
    this.count = 0;
};
    CharCounter.prototype.updateAll = function() {
        this.count = document.getElementById(this.sourceId).value.length;
        document.getElementById(this.statusId).innerHTML = "There are "+this.count+" charactors";
    };

function start() {
    myCharCounter.updateAll();
    document.getElementById('mytextfield').onkeyup = function() { myCharCounter.updateAll(); };
    document.getElementById('mytextfield').onkeydown = function() { myCharCounter.updateAll(); };   
};

myCharCounter = new CharCounter('mytextfield','charcount');
window.onload = start;

实现方式2

function CharCounter(sourceId, statusId) {
    this.sourceId = sourceId;
    this.statusId = statusId;
    this.count = 0;
};
    CharCounter.prototype.updateAll = function() {
        this.count = document.getElementById(this.sourceId).value.length;
        document.getElementById(this.statusId).innerHTML = "There are "+ this.count+" charactors";
    };
    CharCounter.prototype.start = function() {
        var instance = this;
        instance.updateAll();

        document.getElementById(this.sourceId).onkeyup = function() {
            instance.updateAll();
        };
        document.getElementById(this.sourceId).onkeydown = function() {
            instance.updateAll();
        };
    };

window.onload = function() {
    var myCounter = new CharCounter("mytextfield","charcount");
    myCounter.start();
};

实施3

function CharCounter(sourceId, statusId) {
    this.sourceId = sourceId;
    this.statusId = statusId;
    this.count = 0;
};
    CharCounter.prototype.updateAll = function() {
        this.count = document.getElementById(this.sourceId).value.length;
        document.getElementById(this.statusId).innerHTML = "There are "+this.count+" charactors";
    };

function bind(funcToCall, desiredThisValue) {
    return function() { funcToCall.apply(desiredThisValue); };
};  

function start() {
    myCharCounter.updateAll();
    document.getElementById('mytextfield').onkeyup = bind(myCharCounter.updateAll,    myCharCounter);
    document.getElementById('mytextfield').onkeydown = bind(myCharCounter.updateAll, myCharCounter);
};

myCharCounter = new CharCounter('mytextfield','charcount');
window.onload = start;
5个回答

2
表达式“myCounter.updateAll”仅返回绑定到“updateAll”的函数对象的引用。这个引用没有什么特别之处——具体而言,没有任何“记住”该引用来自您的“myCounter”对象的属性。
您可以编写一个接受函数作为参数并返回一个新函数的函数,该函数专门用于使用特定对象作为“this”指针运行您的函数。许多库都有类似的例程;例如,“functional.js”库及其“bind”函数。下面是一个真正简单的版本:
function bind(funcToCall, desiredThisValue) {
  return function() { funcToCall.apply(desiredThisValue); };
}

现在你可以写如下代码:

document.getElementById('myTextField').onkeydown = bind(myCounter.updateAll, myCounter);

2

我认为您在updateAll函数中访问实例成员时遇到了问题,因为您将其用作事件处理程序时,上下文(this关键字)是触发事件的DOM元素,而不是CharCounter对象实例。

您可以尝试以下方法:

function CharCounter(sourceId, statusId) {
    this.sourceId = sourceId;
    this.statusId = statusId;
    this.count = 0;
}

CharCounter.prototype.updateAll = function() {
  var text = document.getElementById(this.sourceId).value;
  document.getElementById(this.statusId).innerHTML = text.length;
};

CharCounter.prototype.start = function() {
  // event binding
  var instance = this; // store the current context
  document.getElementById(this.sourceId).onkeyup = function () {
    instance.updateAll(); // use 'instance' because in event handlers
                          // the 'this' keyword refers to the DOM element.
  }; 
}

window.onload = function () {
  var myCharCounter = new CharCounter('textarea1', 'status');
  myCharCounter.start();
};

Check the above example running here.


谢谢!这为我的问题提供了很多启发! - user182666

0

您可以:

function start() {
    //This is the problem
    document.getElementbyId('mytextfield').onkeydown = function() { myCounter.updateAll(); };
    document.getElementbyId('mytextfield').onkeyup = function() { myCounter.updateAll(); };
}

0
我想做类似于这个但更简单的事情。 这个想法是让用户点击加粗的文本,然后出现一个文本框,他们可以在其中更改角色扮演角色的所有值。然后当值被更改时,让文本框再次消失,用更新后的加粗文本值替换。 我已经使用令人烦恼的文本框警报来实现了这一点。但我宁愿有类似下面的东西来代替所有这些。 我已经搜索了几个月,CMS是以最简单的方式提供完整HTML示例来回答我的问题的最接近的答案。其他网站上没有人能够提供这样的答案。
所以我的问题是,我该怎么做? 我有多个对象(角色),需要this.elementId来使其工作。
我修改了这个例子,但如果我尝试添加到它,它就会崩溃。 沙盒

谢谢EFraim和Ryu!另外,在JQuery 1.4.4中,我该如何将-- response=$("getName").val() 和 response=$(this).val() 结合在同一语句中? - ren1999

0

在ASP.Net Ajax中,您可以使用

Function.createDelegate(myObject, myFunction); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接