如何在javascript中添加原型中的事件监听器?

时间:2016-08-24 11:43:37

标签: javascript prototype

浏览器出现错误(Uncaught TypeError:this.showCheckedNums不是函数)当我单击复选框时。

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>
&#13;
&#13;
&#13;

我是初学者,我不知道错误发生的原因。我希望有人能帮助我解释错误,谢谢。

2 个答案:

答案 0 :(得分:0)

添加.addEventListener的函数,需要将该函数绑定到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));

请注意我添加的.bind(this)。有四种方法可以在JavaScript函数中确定this。请参阅此lecture

更好的方法来做你想做的事情就像这样:

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

答案 1 :(得分:0)

这是没有错误的代码。

我建议您阅读this关键字,因为当您是JS初学者时,它会非常混乱。以下是一个解释: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>