我正在完成 TheOdinProject 的 Etch-a-Sketch 项目。我想访问网格的单元格以更改其颜色,但它们是在
for()
循环的范围内创建的,并且 for()
循环位于函数的范围内。我搜索了其他问题,但没有得到我想要的,或者也许我无法理解所传达的内容。
创建网格功能
function changeGridSize(number) {
let container = document.getElementById(`container`);
totalNumber = number * number;
while (container.hasChildNodes()) {
container.removeChild(container.firstChild);
}
for (let i = 0; i < totalNumber; i++) {
let gridSquare = document.createElement("div");
gridSquare.classList.add("grid_square");
let cellwidth = container.clientWidth / number + `px`;
let cellheight = container.clientHeight / number + `px`;
gridSquare.setAttribute(
`style`,
`width: ${cellwidth}; height: ${cellheight};`
);
container.appendChild(gridSquare);
}
}
改变颜色的代码
let color = document.getElementById(`colour_picker`);
color.addEventListener(`change`, changeColor() );
let choosenColour = color.value;
function changeColor() {
while (container.hasChildNodes()) {
gridSquare.setAttribute(`style`, `background-color: ${choosenColour};`)
}
}
当用户从颜色选择器中选择颜色时,单元格的背景颜色应更改为用户选择的颜色。 但是,当我将
change
事件侦听器添加到颜色选择器时,页面崩溃,并且当我尝试将网格大小更改为 40x40 以上时。
您的代码中存在一个主要问题,即如何通过调用回调函数而不是使用其值将回调函数传递给
addEventListener
。
也就是说,我只是通过直接使用元素的
style
属性,而不是更改 style
属性的值,简化了以编程方式设置元素样式的方式。
我还决定根据我的口味对您未共享的 html 进行样式设置,最重要的是将
#container
设置为弹性盒以容纳内部的 n*n
方块。
let container = document.getElementById(`container`);
//on page loaded, click the #resetGrid button
document.addEventListener('DOMContentLoaded', ()=>{
document.getElementById('resetGrid').click();
})
//on click over the #resetGrid button, changeGridSize() accordingly
document.getElementById('resetGrid')
.addEventListener('click', (event)=>{
const size = document.getElementById('gridsize').value;
changeGridSize(size);
});
//empty the #container and add a number of div.grid_square based on arg number
function changeGridSize(number) {
totalNumber = number * number;
while (container.hasChildNodes()) {
container.removeChild(container.firstChild);
}
for (let i = 0; i < totalNumber; i++) {
let gridSquare = document.createElement("div");
gridSquare.classList.add("grid_square");
let cellwidth = container.clientWidth / number;
let cellheight = container.clientHeight / number;
gridSquare.style.width = `${cellwidth}px`;
gridSquare.style.height = `${cellheight}px`;
container.appendChild(gridSquare);
}
}
let color = document.getElementById(`colour_picker`);
color.addEventListener(`change`, changeColor);
//called when #color_picker change event triggers,
//setting the background of each single .grid_square accordingly
function changeColor(event) {
for (let box of container.children) {
box.style.background = this.value;
}
}
body {
display: flex;
justify-content: space-around;
align-items: center;
padding-top: 3em;
}
#container {
width: 100px;
height: 100px;
border: solid 1px black;
display: flex;
flex-wrap: wrap;
}
.grid_square {
border: solid 1px;
box-sizing: border-box;
}
/*controls styles*/
.controls label[for="color_picker"]{
vertical-align: text-bottom;
}
.controls .input-group {
display: flex;
align-items: center;
}
.controls #gridsize{
width: 2em;
margin-right: .5em;
}
.controls button{
width: 100%;
cursor: pointer;
}
<body>
<div id="container"></div>
<div class="controls">
<label for="colour_picker">Pick a color:</label>
<input id="colour_picker" type="color">
<br><br>
<div class="input-group">
<input id="gridsize" type="number" value="4" style="width: 50px;">
<button id="resetGrid">Reset</button>
</div>
</div>
</body>