我试图使形状在单击后出现一次。 1.2秒后,它出现,然后单击消失,然后重复整个过程。问题是单击几下就会出现两个形状。
这是程序的链接。 https://jsfiddle.net/EyedFox/w98naLjx/2/
function show() {
var randomColor = colors[Math.floor(colors.length * Math.random())]; // Random color chosen
var randomX = Math.floor(Math.random() * 60); // random x axis margin
var randomY = Math.floor(Math.random() * 80); // random y axis margin
square = document.getElementById("square");
circle = document.getElementById("circle");
var shapeArray = [square, circle];
var randShape = shapeArray[Math.floor(shapeArray.length * Math.random())];
randShape.style.margin = randomX + "% " + randomY + "%";
randShape.style.backgroundColor = randomColor;
randShape.style.display = "block";
randShape.addEventListener("click", click);
function click() {
randShape.style.display = "none";
setTimeout(show, 1200);
}
}
setTimeout(show, 1200);
答案 0 :(得分:3)
您的代码不断将click事件监听器添加到randShape中,但它从未清除这些事件。结果,它们不断被添加,click
(因此show
)每次点击都会执行几次。尝试在点击功能的开头添加console.log('clicked on', randShape);
来查看它。如果偶然的情况下,所有show
执行都选择了相同的形状,则您只会在屏幕上看到该形状,否则将会得到两者。
您的click
函数应如下所示:
function click() {
console.log('clicked on', randShape);
randShape.style.display = "none";
setTimeout(show, 1200);
randShape.removeEventListener('click', click); // cleaning after myself ;-)
}
(btw (function() { ... })()
在加载时不是 执行,而是在javascript vm遇到后立即执行)
答案 1 :(得分:0)
这是解决问题的小提琴。
根据@autra回复编辑了我的回复
在重新绘制之前,我可能会彻底清洁画布:
https://jsfiddle.net/c0L54uk3/
基本上是这样的复位功能:
function reset(){
square = document.getElementById("square").style.display = "none";
circle = document.getElementById("circle").style.display = "none";
randShape.removeEventListener("click", click);
}
并在click()函数开始时调用它以重置画布,如下所示:
function click() {
reset();
setTimeout(show, 1200);
}
希望有帮助。
答案 2 :(得分:0)
addEventListener()
应该在回调函数之外(即show()
)。有一个事件侦听器被添加到clicked标记中,但是没有一个被删除。因此,当发生第4到第7次点击时,浏览器开始放慢速度,并且setTimeout
永远不会是1.2秒,因为它将提示启动,这意味着它将等待很长时间然后再等待1.2秒。随着提示的累积,点击次数将超过setTimeout
。
注册父标记.container
,以监听其所有子标记的click事件事件。此模式称为Event Delegation。这样,您可以仅使用一个事件监听器(而不是每个形状一个监听器)将click事件添加到.container
中的无限数量的标签中。
#triangle
从未设置样式,因此它是一个不可见的div,它在周围浮动。在演示中,我为#triangle
设置了样式,并添加了以金色轮廓的.blank
<div>
(您可以删除.blank
)。
演示中评论的详细信息
// Reference parent tag
var box = document.querySelector('.container');
function show() {
// Collect all .shape into a NodeList and convert into an array
var shapes = Array.from(document.querySelectorAll('.shape'));
var colors = ["yellow", "red", "green", "purple", "aqua", "chartreuse", "coral", "dodgerBlue", "deepPink"];
var rColor = colors[Math.floor(colors.length * Math.random())];
var rX = Math.floor(Math.random() * 60);
var rY = Math.floor(Math.random() * 80);
var rShape = shapes[Math.floor(shapes.length * Math.random())];
rShape.style.margin = rX + "% " + rY + "%";
// if #triangle change the border-bottom-color
if (rShape.id === 'triangle') {
rShape.style.borderBottomColor = rColor;
// otherwise change background-color
} else {
rShape.style.backgroundColor = rColor;
}
rShape.style.display = "block";
}
/*
Run show()
A setTimeout nor an IIFE is needed to initially run show()
Simply call it.
*/
show();
// Register box to click event...
box.addEventListener('click', function(e) {
// ...reference the clicked tag (i.e. .shape)...
var tgt = e.target;
// ...reference the registered parent tag...
var cur = e.currentTarget;
/*
...if the clicked tag IS NOT the registered parent tag...
*/
if (tgt !== cur) {
// ...then hide clicked element...
tgt.style.display = "none";
// ...and run show() in about 1.2 seconds
setTimeout(show(), 1200);
}
});
.container {
overflow: hidden;
height: 800px;
width: 80%;
background-color: rgb(0, 34, 85);
margin: 0 auto;
margin-top: 5em;
}
#square {
width: 80px;
height: 80px;
background-color: red;
margin-left: 0%;
margin-top: 10%;
display: none
}
#circle {
width: 100px;
height: 100px;
background: red;
border-radius: 50px;
display: none
}
#triangle {
width: 0;
height: 0;
border-left: 45px solid transparent;
border-right: 45px solid transparent;
border-bottom: 90px solid cyan;
display: none
}
.shape {
cursor: pointer
}
.blank {
outline: 10px solid gold
}
<div class="container">
<div id="square" class='shape'></div>
<div id="triangle" class='shape'></div>
<!--
This .blank represents what #triangle was before it
had any style.
-->
<div class='blank'></div>
<div id="circle" class='shape'></div>
</div>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />