Javascript-element.addEventListener()返回;未捕获类型错误“;
在上下文中,我试图编写一个记忆游戏,在这个游戏中,你必须配对两个相同颜色的圆圈,直到整个棋盘完成。我称之为第二场比赛。下面是我将从中引用的代码:Javascript-element.addEventListener()返回;未捕获类型错误“;,javascript,html,css,Javascript,Html,Css,在上下文中,我试图编写一个记忆游戏,在这个游戏中,你必须配对两个相同颜色的圆圈,直到整个棋盘完成。我称之为第二场比赛。下面是我将从中引用的代码: class Circle { constructor(element, circleColor){ this.elem = element; this.color = circleColor; } } var frequency = [0, 0, 0, 0, 0, 0, 0, 0]; var num;
class Circle {
constructor(element, circleColor){
this.elem = element;
this.color = circleColor;
}
}
var frequency = [0, 0, 0, 0, 0, 0, 0, 0];
var num;
var hue = new Array(8);
var circle = new Array(16);
hue[0] = "#0039ff";
hue[1] = "#ff0000";
hue[2] = "#43ff00";
hue[3] = "#fffa00";
hue[4] = "#7405b5";
hue[5] = "#ff9d00";
hue[6] = "#ff00c3";
hue[7] = "#00fff6";
onload = function() {
for(var i = 0; i < 16; i++){
circle[i] = new Circle(document.getElementById("circle" + i));
while(circle[i].color === undefined){
num = Math.floor(Math.random() * 8);
if(frequency[num] != 2){
frequency[num]++;
circle[i].color = hue[num];
circle[i].elem.addEventListener('click', function(){
main(circle[i])
});
}
}
}
}
function main(circle){
circle.elem.style.backgroundColor = circle.color;
}
因此,我在其中放入了一些console.log()函数,以查看发生了什么:
if(frequency[num] != 2){
frequency[num]++;
circle[i].color = hue[num];
console.log(circle[i].elem);
console.log(circle[i].color);
circle[i].elem.addEventListener('click', function(){
main(circle[i])
});
}
这正是我所期望的:
script.js:31 #ff9d00
script.js:30 div data-brackets-id="11" class="circle" id="circle1" /div
script.js:31 #ff9d00
script.js:30 div data-brackets-id="12" class="circle" id="circle2" /div
script.js:31 #0039ff
script.js:30 div data-brackets-id="13" class="circle" id="circle3" /div
script.js:31 #0039ff
因此它返回元素引用和圆的颜色。因此,我尝试将“circle[I].elem.style.backgroundColor=circle[I].color”放入事件侦听器,我得到了与之前相同的问题
if(frequency[num] != 2){
frequency[num]++;
circle[i].color = hue[num];
console.log(circle[i].elem);
console.log(circle[i].color);
circle[i].elem.addEventListener('click', function(){
circle[i].elem.style.backgroundColor = circle[i].color
});
}
所以我放弃了,决定在事件监听器之外编写那行代码,看看它是否有效,它将所有圆圈的颜色都更改为它们的特定颜色
if(frequency[num] != 2){
frequency[num]++;
circle[i].color = hue[num];
console.log(circle[i].elem);
console.log(circle[i].color);
circle[i].elem.style.backgroundColor = circle[i].color;
circle[i].elem.addEventListener('click', function(){
circle[i].elem.style.backgroundColor = circle[i].color
});
}
事件侦听器无法传递圆或其他对象时出现问题。。。我不知道,请帮忙:(你的问题归结为JS对待
var
变量的方式——它们有点“泄漏”到全局范围
考虑已附加的事件侦听器:
circle[i].elem.addEventListener('click', function(){
main(circle[i])
});
因此,每当监听器被触发时,它调用main()
函数并传递circle[i]
进入它。但由于i
是泄漏到假定范围之外的变量,因此它的值始终为16
——在for
循环的最后一次迭代中分配给它的值。这就是main()
函数尝试访问未定义的的样式
属性-传递给它的是圆圈[16]
的值
以下是几种修复方法:
如果可以使用ES6let
变量:
在for
循环中使用let i
而不是var i
:
for (let i = 0; i < 16; i++) {
//...
}
这里有一个有用的主题,提供了更多的技术来避免这种情况:您的问题归结为JS处理var
变量的方式——它们有点“泄漏”到全局范围
考虑已附加的事件侦听器:
circle[i].elem.addEventListener('click', function(){
main(circle[i])
});
因此,每当监听器被触发时,它调用main()
函数并传递circle[i]
进入它。但由于i
是泄漏到假定范围之外的变量,因此它的值始终为16
——在for
循环的最后一次迭代中分配给它的值。这就是main()
函数尝试访问未定义的的样式
属性-传递给它的是圆圈[16]
的值
以下是几种修复方法:
如果可以使用ES6let
变量:
在for
循环中使用let i
而不是var i
:
for (let i = 0; i < 16; i++) {
//...
}
这里有一个有用的主题,它提供了更多的技术来避免这种情况:您能否再次生成此错误消息,然后复制它所指向的代码行(在过去的某个时候是第39行)并将其粘贴到您的问题中,这样我们就可以看到哪个代码触发了错误?uncaughttypeerror:cannotread属性'elem'of undefined at main(script.js:39)
尝试在for循环声明中使用let i=0
而不是var i=0
,您是否可以再次生成此错误消息,然后复制它所指向的代码行(在过去的某个时候是第39行)并将其粘贴到您的问题中,以便我们可以看到哪个代码触发了错误?uncaughttypeerror:无法读取main(script.js:39)未定义的属性“elem”
尝试在for循环声明中使用let i=0
而不是var i=0
function createListener(j) {
return function () {
main(circle[j])
}
}
// and use it in your 'for' loop later:
circle[i].elem.addEventListener('click', createListener(i));