简体   繁体   中英

JavaScript event handler in progressbar prototype comes up with undefined value

I am currently building a JavaScript object that creates a progress bar and allows the progress bar value to be incremented using click listeners on certain elements.
I am having a problem whereby when I click on a button that should increment the current value, it says the value is NaN when I alert this value to the window and I am not sure why.

Here is my code:

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

And the code to create an instance of the object

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

Why is 'this.currentVal' property returning NaN from within the addAmount and removeAmount functions?

you need to bind your this to your function...

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

if you use something like underscore you can do something a bit more tricky, have a single :-

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

and then :-

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

When you add this.addAmount or this.removeAmount as the event handler, it will be called in the context of the element, not the ProgressBar instance.

To work around this, you can use bind() to force it to be called in the correct context.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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