对于情况下,我想编写一个记忆游戏,你必须对的两个相同颜色的圆圈,直到整个板是完整的。我把它叫做匹配两种。下面是我将从引用的代码:
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对象从我的html文档元素引用(有16个圆圈和他们每个人都有circle0,CIRCLE1,CIRCLE2 ..等的ID,然后在有一个小的算法,以确保只有两个矩阵中的每个颜色,使他们都有一个匹配对在for循环每次迭代中,我添加事件侦听到每个圆圈。如果点击了一圈,我希望它改变其颜色存储在颜色[I]。颜色然而,当我点击圈子中的所有返回是:
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...
有一些问题不能够通过一个圆或某事的对象的事件监听器......我不知道,请帮助:(
你的问题可以归结为这样JS对待var
变量 - 样的,他们“泄漏”到全球范围内。
想想看,你已经附加了事件侦听器:
circle[i].elem.addEventListener('click', function(){
main(circle[i])
});
所以,每当听众被触发,它调用main()
函数,并将circle[i]
进去。但由于i
是这就是所谓范围向外泄漏的变量,它总是有16
的价值 - for
循环的最后一次迭代中分配给它的价值。这就是为什么main()
函数试图访问style
的undefined
属性 - 它是在传递给它的circle[16]
的价值。
这里有一对夫妇的方式来解决这个问题:
let
变量:在let i
循环使用var i
代替for
的:
for (let i = 0; i < 16; i++) {
//...
}
function createListener(j) {
return function () {
main(circle[j])
}
}
// and use it in your 'for' loop later:
circle[i].elem.addEventListener('click', createListener(i));
下面是提供了更多的技术来避免这样的有用话题:JavaScript closure inside loops – simple practical example