有关背景下,我想代码记忆游戏,你必须要对的两个相同颜色的圆圈,直到整个板是完整的。我称它为Match-Two。下面是代码,我会从参考:
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;
}
因此,在此代码中,我创建了一个Circle类,并创建了一个Circle对象数组,这些对象被标识为“ circle”。当加载页面时,我给每个圆圈对象从我的html文档元素引用(有16个圆圈和他们每个人都有circle0,CIRCLE1,CIRCLE2 ..等的ID,然后在有一个小的算法,以确保只有两个矩阵中的每个颜色,使他们都有一个匹配对在for循环每次迭代,我一个事件侦听器添加到每个圆圈。如果点击了一圈,我也想改变它的颜色存储在颜色[i] .color。但是,当我单击圆圈时,它返回的只是:
Uncaught TypeError: Cannot read property 'elem' of undefined
at main (script.js:39)
at HTMLDivElement.<anonymous> (script.js:31)
正在引用:
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
所以它返回元件和参考圆的颜色。于是我尝试把“圈子[I] .elem.style.backgroundColor =圈子[I]。颜色”到事件监听器,我也得到了同样的问题...
在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
});
}
The circles with their specific colors...
有一些问题不能够通过一个圆或某事的对象的事件监听器......我不知道,请帮助:(
答案 0 :(得分:0)
您的问题归结为JS处理var
变量的方式-它们有点“泄漏”到全局范围中。
考虑您已附加的事件侦听器:
circle[i].elem.addEventListener('click', function(){
main(circle[i])
});
因此,只要触发了侦听器,它就会调用main()
函数并将circle[i]
传递给该函数。但是,由于i
是泄漏到假定范围之外的变量,因此它始终具有16
的值-在for
循环的最后一次迭代期间分配给它的值。这就是main()
函数试图访问style
的{{1}}属性的原因-这是传递给其中的undefined
的值。
以下是几种修复方法:
circle[16]
变量:在let
循环中使用let i
代替var i
:
for
for (let i = 0; i < 16; i++) {
//...
}
这是一个有用的主题,它提供了避免这种情况的更多技术:JavaScript closure inside loops – simple practical example