progressbar原型中的JavaScript事件处理程序带有未定义的值

时间:2014-11-04 10:15:27

标签: javascript jquery oop nan

我目前正在构建一个JavaScript对象,该对象可以创建一个进度条,并允许使用某些元素上的单击侦听器来增加进度条值。
我遇到了一个问题,当我点击一个应该增加当前值的按钮时,它表示当我将此值提醒到窗口时值为NaN,我不知道为什么。

这是我的代码:

//Progress Bar
var ProgressBar = function(element, startVal, endVal, step, addLefts, addRights) {
    this.element = element;
    this.endVal = endVal;
    this.currentVal = startVal;
    this.step = step;
    this.addLefts = addLefts;
    this.addRights = addRights;
    var self = this;    
}

ProgressBar.prototype.initializeProgressBar = function() {
    jQuery(this.element).progressbar({
        value : this.currentVal
    });
    for(var i = 0; i < this.addLefts.length; i++) {
        this.addLefts[i].addEventListener("click", this.removeAmount, false);
    }   
    for(var i = 0; i < this.addRights.length; i++) {
        this.addRights[i].addEventListener("click", this.addAmount, false);
    }   
}

ProgressBar.prototype.addAmount = function() {  
    this.currentVal += this.step;       
    alert(this.currentVal);
}

ProgressBar.prototype.removeAmount = function() {
    this.currentVal -= this.step;
    alert(this.currentVal);
}

创建对象实例的代码

var addLefts = document.getElementsByClassName("btn-left");
var addRights = document.getElementsByClassName("btn-right");
var progressBar = new ProgressBar("#progress-bar", 0, jQuery(".signup-part").length, 1, addLefts, addRights);
progressBar.initializeProgressBar();

为什么'this.currentVal'属性从addAmountremoveAmount函数中返回NaN?

2 个答案:

答案 0 :(得分:3)

你需要把它绑定到你的功能......

this.addRights[i].addEventListener("click", this.addAmount.bind(this), false);

如果你使用像下划线这样的东西你可以做一些更棘手的事情,有一个: -

ProgressBar.prototype.change = function(sign) {
    this.currentVal += (this.step * sign);
}

然后: -

this.addLefts[i].addEventListener("click",  _.partial(this.change,-1).bind(this), false);
this.addRights[i].addEventListener("click", _.partial(this.change, 1).bind(this), false);

答案 1 :(得分:3)

当您添加this.addAmountthis.removeAmount作为事件处理程序时,它将在元素的上下文中调用,而不是ProgressBar实例。

要解决此问题,您可以使用bind()强制在正确的上下文中调用它。

for(var i = 0; i < this.addLefts.length; i++) {
    this.addLefts[i].addEventListener("click", this.removeAmount.bind(this), false);
}