如何在javascript中访问尚未创建的元素?

问题描述 投票:0回答:1

我正在完成 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 以上时。

javascript html frontend addeventlistener event-listener
1个回答
0
投票

您的代码中存在一个主要问题,即如何通过调用回调函数而不是使用其值将回调函数传递给

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>

© www.soinside.com 2019 - 2024. All rights reserved.