简体   繁体   中英

How to add a event listener in prototype in javascript?

The browsers thorw an error(Uncaught TypeError: this.showCheckedNums is not a function) When I click a checkbox.

HTML Souce Code:

 <!DOCTYPE html PUBLIC "-//W3C//Dth XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/Dth/xhtml1-transitional.dth"> <html xmlns="http://www.w3.org/1999/xhtml"> <meta charset="UTF-8"> <head> </head> <body> <input type="checkbox" value="1" id="check0" name="ck" />num1 <input type="checkbox" value="2" id="check1" name="ck"/>num2 <input type="checkbox" value="4" id="check2" name="ck"/>num3 <input type="checkbox" value="8" id="check3" name="ck"/>num4 <hr /> result:<label id="ckRes">0</label> <hr /> </body> </html> <script> function ckCheck (mask,name) { this.mask = mask;//mask code this.name = name;//css selector this.temp = mask;//cache this.nodes = []; } ckCheck.prototype={ start:function () { this.nodes = document.getElementsByName(this.name); this.default(); this.addEvtLisener(); }, showCheckedNums:function(argument){ document.getElementById("ckRes").innerHTML= this.temp; }, default:function (argument) { //back to initial value for(var j = 0;j<this.nodes.length ;j++){ //init checkbox this.nodes[j].checked = this.nodes[j].value & this.mask ;//1 }; this.showCheckedNums(); }, addEvtLisener:function(){ for(var i = 0; i < this.nodes.length; i++){ this.nodes[i].addEventListener('click', function (e) { e.target.checked ? this.temp|=e.target.value:this.temp^=e.target.value; //this.temp can be accessed correctly. this.showCheckedNums(); }) } }, } var obj = new ckCheck(7,"ck") obj.start(); </script> 

I am a beginner ,I don't konw why the error happened.I hope someone can help me to explain the error,thanks.

The function where you add .addEventListener , you need to bind that function to your this object, like this:

this.nodes[i].addEventListener('click', function (e) {
    e.target.checked ? this.temp|=e.target.value:this.temp^=e.target.value;
                //this.temp can be accessed correctly.
    this.showCheckedNums();
}.bind(this));

Notice the .bind(this) I added. There are four ways how this is determined in JavaScript functions. See this lecture .

A better way to do what you are trying to do would be like this:

function onClick(e) {
    e.target.checked ? this.temp|=e.target.value:this.temp^=e.target.value;
    this.showCheckedNums();
};
var onClickBound = onClick.bind(this);
this.nodes[i].addEventListener('click', onClickBound);

Here is the code without the error.

I suggest you read up on the this keyword, because it is very confusing when you're a JS beginner. Here is one explanation: How does the "this" keyword work?

 <!DOCTYPE html PUBLIC "-//W3C//Dth XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/Dth/xhtml1-transitional.dth"> <html xmlns="http://www.w3.org/1999/xhtml"> <meta charset="UTF-8"> <head> </head> <body> <input type="checkbox" value="1" id="check0" name="ck" />num1 <input type="checkbox" value="2" id="check1" name="ck"/>num2 <input type="checkbox" value="4" id="check2" name="ck"/>num3 <input type="checkbox" value="8" id="check3" name="ck"/>num4 <hr /> result:<label id="ckRes">0</label> <hr /> </body> </html> <script> function ckCheck (mask,name) { this.mask = mask;//mask code this.name = name;//css selector this.temp = mask;//cache this.nodes = []; } ckCheck.prototype={ start:function () { this.nodes = document.getElementsByName(this.name); this.default(); this.addEvtLisener(); }, showCheckedNums:function(argument){ document.getElementById("ckRes").innerHTML= this.temp; }, default:function (argument) { //back to initial value for(var j = 0;j<this.nodes.length ;j++){ //init checkbox this.nodes[j].checked = this.nodes[j].value & this.mask ;//1 }; this.showCheckedNums(); }, addEvtLisener:function(){ var self = this; for(var i = 0; i < this.nodes.length; i++){ self.nodes[i].addEventListener('click', function (e) { e.target.checked ? self.temp|=e.target.value:self.temp^=e.target.value; //this.temp can be accessed correctly. self.showCheckedNums(); }) } }, } var obj = new ckCheck(7,"ck") obj.start(); </script> 

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