我已经创建了一个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>
发布于 2018-10-04 07:38:04
几乎,只有几个变化:
错误元素上的
click
事件;只有td
%s需要指向错误元素的event.td
。( css应该只是tr
s.)div
.赋值给元素的style
属性(注意:td
属性名称是规范化的,不应该将style
附加到table
;请考虑将pixelCanvas
设置为div
.
请注意,this.style...
不是td.style...
;在事件处理程序中,this
引用目标元素。如果使用let
关键字声明td
,但使用关键字var
:learn more about scope here.,则可以使用td.style...
清空表格
清除表很简单:删除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>
发布于 2018-10-04 10:21:28
编辑
添加了重置过程。还将窗体上的内联属性事件(onsubmit)替换为事件侦听器。
不要浪费资源将事件侦听器分配给大量的<td>s
,使用来使用<table>
来侦听所有的<td>
。关于实现该模式的详细信息在demo中进行了注释,以及可以使用的更专业、更少冗长和更有效的替代方法。
演示
在演示中评论的详细信息
/*
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>
https://stackoverflow.com/questions/52636590
复制相似问题