单击单个单元格并使用Javascript向HTML表格添加颜色

时间:2018-10-03 22:35:17

标签: javascript html css

我创建了一个HTML表(用户输入了行和行),并且还具有动态选择颜色的方式。

现在,我希望能够单击表中的单个单元格,并使用选定的颜色为其着色。到目前为止,我已经有了这段代码。

我的最终目标是当我再次点击“提交”时能够重置颜色。流为:

  1. 选择表格大小
  2. 选择颜色
  3. 为表格中的单元格着色
  4. 再次点击“提交”以重置表格

function makeGrid(ev) {
  ev.preventDefault();
  var heights = document.getElementById("inputHeight").value;
  var widths = document.getElementById("inputWidth").value;
  var body = document.getElementById("pixelCanvas");
  var table = document.createElement('TABLE')
  var tblB = document.createElement('TBODY');
  table.appendChild(tblB);
  for (var i=0; i<heights; i++){
    var tr = document.createElement('TR');
    table.appendChild(tr);
    for (var j=0; j<widths; j++){
      var td = document.createElement('TD')
      document.getElementById("pixelCanvas").onclick = function(){
        td = document.getElementById("colorPicker").value;
        alert(td);
      }
      table.appendChild(td);
    }
  }
  body.append(table);
  body.addEventListener('click', function(){
    var coloor = document.getElementById("colorPicker").value;
    body.style.backgroundColor = coloor;
  })
}
body {
    text-align: center;
}

h1 {
    font-family: Monoton;
    font-size: 70px;
    margin: 0.2em;
}

h2 {
    margin: 1em 0 0.25em;
}

h2:first-of-type {
    margin-top: 0.5em;
}

table,
tr,
td {
    border: 1px solid black;
    padding: 25px;
}

table {
    border-collapse: collapse;
    margin: 0 auto;
}

input[type=number] {
    width: 6em;
}
<!DOCTYPE html>
<html>
<head>
    <title>Pixel Art Maker!</title>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Monoton">
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>Pixel Art Maker</h1>

    <h2>Choose Grid Size</h2>
    <form id="sizePicker" onsubmit="makeGrid(event)">
        Grid Height:
        <input type="number" id="inputHeight" name="height" min="1" value="1">
        Grid Width:
        <input type="number" id="inputWidth" name="width" min="1" value="1">
        <input type="submit" value= "submit">
    </form>

    <h2>Pick A Color</h2>
    <input type="color" id="colorPicker">

    <h2>Design Canvas</h2>
    <table id="pixelCanvas"></table>

    <script src="designs.js"></script>
</body>
</html>

2 个答案:

答案 0 :(得分:1)

几乎只有几处更改:

  1. click个关于不正确元素的事件;只有td个需要事件。
  2. td附加到错误的元素。 ({td应当tr分开。)
  3. 应该通过style将颜色选择器的值分配给元素的HTMLElement.prototype.style属性(注意:css属性名称是 normalized [camel-cased])。 / li>
  4. 我们不应将table附加到table上;考虑将pixelCanvas设为div

通知this.style...不是td.style...;在事件处理程序中,this引用目标元素。如果使用td.style...关键字声明let,但您使用td,则使用varlearn more about scope here.

清除表格

清除表很简单:删除pixelCanvas中的元素(将pixelCanvas重置为其原始状态)。分两行完成:

//reset pixelCanvas
while (body.firstChild)
    body.removeChild(body.firstChild);

如果您不会向pixelCanvas添加更多子级,则可以将while更改为if

在一起:

function makeGrid(ev) {
  ev.preventDefault();

  //keep like-statements together
  var rows = document.getElementById("inputHeight").value;
  var cols = document.getElementById("inputWidth").value;
  var table = document.createElement('TABLE');
  var body = document.getElementById("pixelCanvas");
  
  //reset pixelCanvas
  while (body.firstChild)
      body.removeChild(body.firstChild);

  for (var i=0; i<rows; i++){
    var tr = document.createElement('TR');

    for (var j=0; j<cols; j++) {
      var td = document.createElement('td');
      td.onclick = function() {
        this.style.backgroundColor = document.getElementById("colorPicker").value;
      };
      tr.appendChild(td);
    }

    table.appendChild(tr);
 }

 body.append(table);
}
body {
    text-align: center;
}

h1 {
    font-family: Monoton;
    font-size: 70px;
    margin: 0.2em;
}

h2 {
    margin: 1em 0 0.25em;
}

h2:first-of-type {
    margin-top: 0.5em;
}

table,
tr,
td {
    border: 1px solid black;
    padding: 25px;
}

table {
    border-collapse: collapse;
    margin: 0 auto;
}

input[type=number] {
    width: 6em;
}
<!DOCTYPE html>
<html>
<head>
    <title>Pixel Art Maker!</title>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Monoton">
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>Pixel Art Maker</h1>

    <h2>Choose Grid Size</h2>
    <form id="sizePicker" onsubmit="makeGrid(event)">
        Grid Height:
        <input type="number" id="inputHeight" name="height" min="1" value="1">
        Grid Width:
        <input type="number" id="inputWidth" name="width" min="1" value="1">
        <input type="submit" value= "submit">
    </form>

    <h2>Pick A Color</h2>
    <input type="color" id="colorPicker">

    <h2>Design Canvas</h2>
    <table id="pixelCanvas"></table>

    <script src="designs.js"></script>
</body>
</html>

答案 1 :(得分:1)

编辑

添加了重置过程。还用事件侦听器替换了表单上的内联属性事件(onsubmit)。


不要在将事件侦听器分配给大量<td>s时浪费资源,而是使用Event Delegation来使用<table>来侦听所有<td>。在演示中评论了有关实现该模式的详细信息,以及使用的更专业,更冗长和更有效的替代方法。

演示

演示中评论的详细信息

/*
Register the first (and only) form to submit event
Look for a node with class .destroy and if present remove it from
DOM.
Call makeGrid()
*/

document.forms[0].addEventListener('submit', function(e) {

  const destroy = document.querySelector('.destroy');

  if (destroy) {
    destroy.parentNode.removeChild(destroy);
  }
  makeGrid(e);

});


function makeGrid(ev) {

  ev.preventDefault();

  /* 
  Since there's a form with multiple form controls we are using
  HTMLFormControlsCollection API.
  Just reference the forms HTMLCollection once...
  */
  var ui = document.forms[0].elements;

  /* 
  ...and then use that reference any and every form control
  nested within that referenced form. (colorPicker was moved into
  the form)
  */
  var rowsQty = ui.inputHeight.value;
  var cellsQty = ui.inputWidth.value;
  var cellColor = ui.colorPicker.value;
  var body = document.getElementById("pixelCanvas");
  var table = document.createElement('TABLE');

  /*
  There's 2 loops: 
  1. first loop: the insertRow() method is used once on each loop. 
     insertRow() advantage is that it creates and appends with one
     call.
  */
  for (let r = 0; r < rowsQty; r++) {

    var rowObj = table.insertRow();

    /*
    2. second loop: the insertCell() method is used as many times
       as the submited number (cellsQty). insertCell() also 
       creates and appends in one call as well.
    */
    for (let c = 0; c < cellsQty; c++) {

      var cellObj = rowObj.insertCell();

    }

  }

  /*
  We will use Event Delegation so that we only need to register
  the parent node (table) to listen for an event not only for
  itself but for all of the nodes nested within it. BTW, this 
  works perfectly for dynamically created nodes when the number
  of nodes is unknown....
  */
  // Here we are registering table to listen for clicks...
  table.addEventListener('click', function(e) {

    // Reference the origin of event (clicked td)
    var tgt = e.target;
    // Reference the node registered to the event (table)
    var cur = e.currentTarget;

    // if the clicked node IS NOT the table...
    if (tgt !== cur) {

      // ...change its background to whatever value colorPicker has
      tgt.style.background = cellColor;

    }
  });
  // Mark table for reset
  table.classList.add('destroy');

  // Add completed table to DOM
  body.appendChild(table);

}
body {
  text-align: center;
}

h1 {
  font-family: Monoton;
  font-size: 70px;
  margin: 0.2em;
}

h2 {
  margin: 1em 0 0.25em;
}

h2:first-of-type {
  margin-top: 0.5em;
}

table,
tr,
td {
  border: 1px solid black;
  padding: 25px;
}

table {
  border-collapse: collapse;
  margin: 0 auto;
}

input[type=number] {
  width: 6em;
}
<!DOCTYPE html>
<html>

<head>
  <title>Pixel Art Maker!</title>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Monoton">
  <link rel="stylesheet" href="styles.css">
</head>

<body>
  <h1>Pixel Art Maker</h1>

  <h2>Choose Grid Size</h2>
  <form id="sizePicker">
    Grid Height:
    <input type="number" id="inputHeight" name="height" min="1" value="1"> Grid Width:
    <input type="number" id="inputWidth" name="width" min="1" value="1">
    <input type="submit" value="submit">


    <h2>Pick A Color</h2>
    <input type="color" id="colorPicker">
  </form>
  <h2>Design Canvas</h2>
  <table id="pixelCanvas"></table>

  <script src="designs.js"></script>
</body>

</html>