我创建了一个HTML表(用户输入了行和行),并且还具有动态选择颜色的方式。
现在,我希望能够单击表中的单个单元格,并使用选定的颜色为其着色。到目前为止,我已经有了这段代码。
我的最终目标是当我再次点击“提交”时能够重置颜色。流为:
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>
答案 0 :(得分:1)
几乎只有几处更改:
click
个关于不正确元素的事件;只有td
个需要事件。td
附加到错误的元素。 ({td
应当仅与tr
分开。)style
将颜色选择器的值分配给元素的HTMLElement.prototype.style
属性(注意:css属性名称是 normalized [camel-cased])。 / li>
table
附加到table
上;考虑将pixelCanvas
设为div
。通知this.style...
不是td.style...
;在事件处理程序中,this
引用目标元素。如果使用td.style...
关键字声明let
,但您使用td
,则使用var
:learn 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>