如何防止JavaScript延迟从多个按钮点击?



我正在使用Vanilla Javascript进行Odin Project Etch-A-Sketch项目:更多细节。

实时预览:https://purplepineapple123.github.io/etch-a-sketch/

首先,我在javascript中动态创建了div网格,并成功创建了按钮(黑色,迷幻和用户颜色选择)来改变每个子div网格元素的颜色。

我遇到的问题是一个优化问题。每次用户单击按钮时,都会触发该事件,并且在后续单击按钮时不会忘记该事件。例如,如果您单击"迷幻"按钮。5次,然后悬停在网格上,console.log显示你悬停在每个网格上的颜色5次。

请注意,在这个截图中,只有一个网格被突出显示,但是console.log的颜色是每个按钮按下的分层div(我在这个例子中使用了psychedelic-button)。

这个分层问题在"chooseColor""按钮。如果用户使用颜色选择器选择了多种不同的颜色,那么console.log将显示每个mouseEnter事件的指数重复输出。这会导致大量的延迟。

我尝试过的事情:

  • 添加和删除类,而不是更改背景颜色。这工作得很好,除了我不知道如何将迷幻(随机JS选择的颜色)添加到css类。
  • 移除createGrid()主函数之外的变色函数。这没有影响任何东西,因为我认为问题是由多次点击按钮引起的。
  • 将颜色变化函数移到createGrid()函数之外。然后抓住divCol类。将该nodeList转换为Array。添加mouseEnter eventListener forEach元素,然后更改颜色。同样的问题,重复的每个按钮点击。

我如何防止这个div堆叠和延迟从累积的按钮点击?

我代码:

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]>      <html class="no-js"> <!--<![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
</head>
<body>


<main id="main-content">         
<div id="description-container">
<h1 class="animate" id="title">text h1</h1>
<p class="animate" id="desc 1">Text p</p>
</div>
<div id="button-container">
<button id="black-button">Black</button>
<button id="psych-button">Pschedelic</button>
<div>
<input type="color" name="chooseColor" id="chooseColor"
value="#9e0a00">
<label for="chooseColor">Choose A Color</label>
</div>
<!-- <button id="sixteenGrid" >Normal</button>
<button id="fourtyGrid">Large</button> -->
<button id="erase-button">Erase</button>
<button id="reset-button">Reset</button>
</div>
<div id="grid-container"></div>
<!-- <div class="sliderContainer">
<button id="reset-button"></button>
<input type="range" min="1" max="50" value="25" class="slider" id="myRange">
</div> -->
</main>
<script src="main.js" async defer></script>
</body>
</html>

JavaScript

//Generate grid to size of user input
function createGrid(widthHeight){
document.getElementById(`grid-container`).innerHTML = "";
for (let i = 0; i < widthHeight; i++) {
let divRow = document.createElement(`div`);
divRow.classList.add(`divRow`);
document.getElementById(`grid-container`).appendChild(divRow);
for (let y = 0; y < widthHeight; y++){
let divCol = document.createElement(`div`);
divCol.classList.add(`divCol`);
divRow.appendChild(divCol);

//default hover
divCol.addEventListener("mouseenter", function(){
this.classList.add(`black-button`);
this.classList.remove(`psych-button`);
});
//black button
document.getElementById(`black-button`).addEventListener(`click`, function() {
divCol.addEventListener("mouseenter", function(){
this.style.backgroundColor = `black`;
});
});
//psychedlic button selection
document.getElementById(`psych-button`).addEventListener(`click`, function() {
divCol.addEventListener("mouseenter", function(){
this.style.backgroundColor = `#${randomColor()}`;
});
});
//Choose color button
document.getElementById(`chooseColor`).addEventListener(`input`, function() {
divCol.addEventListener("mouseenter", function(){
this.style.backgroundColor = `${chooseColor()}`;
});
}, false);
//eraser button
document.getElementById(`erase-button`).addEventListener(`click`, function() {
divCol.addEventListener("mouseenter", function(){
this.style.backgroundColor = `rgb(156, 149, 136)`;
});
}); 
}  
}
}
createGrid(5);
//return the color choosen by the user
function chooseColor(){
let color = document.getElementById(`chooseColor`).value;
console.log(color);
return color;
}
//returns random colors for psychedleic button
function randomColor() {
let randomColor = Math.floor(Math.random()*16777215).toString(16);
console.log(randomColor);
return randomColor;
}

CSS

/* http://meyerweb.com/eric/tools/css/reset/ 
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
background-color: aqua;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
button {
padding: 15px;
}
/* begin CSS styling */
#main-content {
display: flex;
width: 100%;
height: 100vh;
flex-direction: column;
}
#description-container {
background-color: orange;
margin-left: auto;
margin-right: auto;
text-align: center;
margin-top: 3%;
}
#button-container {
background-color: green;
margin-left: auto;
margin-right: auto;
display: inline-flex;
margin-top: 1%;
}
#grid-container {
background-color: rgb(156, 149, 136);
display: flex;
flex-direction: column;
margin-left: auto;
margin-right: auto;
width: 600px;
height: 600px;
text-align: center;
margin-top: 1%;
}
.divRow {
display: flex;
width:100%;
height:100%;
margin-top: 1px;
}
.divCol {
flex: auto;
border-right: 1px solid #ccc;
border-bottom:1px solid #ccc;
margin-right: 1px;
}  
.reset-color{
background-color: rgb(156, 149, 136);
}
.black-button {
background-color: black;
}
.psych-button {
background-color: red;
}

您的问题是,您目前正在创建新的事件侦听器,每次单击您的一个按钮。这些永远不会被销毁,所以当你发送心理按钮时,你创建了一堆事件监听器,它们都会持续存在,并在你进入一个正方形时触发。

一个更好的方法是创建你的事件监听器一次,并保持一个全局变量的颜色,只有当你点击你的一个按钮更新。

let color = ""; // new variable to hold color value
function createGrid(widthHeight) {
document.getElementById(`grid-container`).innerHTML = "";
for (let i = 0; i < widthHeight; i++) {
let divRow = document.createElement(`div`);
divRow.classList.add(`divRow`);
document.getElementById(`grid-container`).appendChild(divRow);
for (let y = 0; y < widthHeight; y++) {
let divCol = document.createElement(`div`);
divCol.classList.add(`divCol`);
divRow.appendChild(divCol);
divCol.addEventListener("mouseenter", function () {
this.style.backgroundColor = color;
});
}
}
}
createGrid(5);
//black button
document.getElementById(`black-button`).addEventListener(`click`, function () {
color = "black";
});

要让心理按钮在这个新设置下工作,您可以存储一个全局布尔值,该值定义是否应该动态生成随机颜色,并在mouseenter事件侦听器中检查该值是否为真,并在那里生成颜色。像这样:

let color = "";
let psychColor = false;
function createGrid(widthHeight) {
document.getElementById(`grid-container`).innerHTML = "";
for (let i = 0; i < widthHeight; i++) {
let divRow = document.createElement(`div`);
divRow.classList.add(`divRow`);
document.getElementById(`grid-container`).appendChild(divRow);
for (let y = 0; y < widthHeight; y++) {
let divCol = document.createElement(`div`);
divCol.classList.add(`divCol`);
divRow.appendChild(divCol);
divCol.addEventListener("mouseenter", function () {
if (psychColor) {
color = `#${randomColor()}`;
}
this.style.backgroundColor = color;
});
}
}
}
createGrid(5);
//black button
document.getElementById(`black-button`).addEventListener(`click`, function () {
psychColor = false;
color = "black";
});
//psychedlic button selection
document.getElementById(`psych-button`).addEventListener(`click`, function () {
psychColor = true;
});
//returns random colors for psychedleic button
function randomColor() {
let randomColor = Math.floor(Math.random() * 16777215).toString(16);
return randomColor;
}

最新更新