我正试图用纯JS并基于CSS和HTML GUI为我的学校制作井字游戏。我知道这可能不是最好的方法,但我认为这可能有效。不幸的是,它根本不起作用。
我正在尝试在Board.generate()
中用JS生成整个电路板,因为我想使我的电路板可调整大小,然后将事件侦听器添加到每个生成的单元格中,但这是行不通的。 Onclick仅在最后一个元素上调用,而不在先前的元素上调用。我想我可以通过创建一个函数来绕过此问题,但是我想了解为什么我的代码无法正常工作。
这是我的代码:
class Board {
constructor(size) {
this.size = size;
this.cells = [];
for (let x = 0; x < size; x++) {
this.cells[x] = [];
for (let y = 0; y < size; y++) {
this.cells[x][y] = new Cell(x, y, null);
}
}
}
generate() {
document.getElementById('game').innerHTML = '<div id="board"></div>';
let boardEl = document.getElementById('board');
for (let y = 0; y < this.size; y++) {
boardEl.innerHTML += '<div id="r' + y + '" class="board-row"></div>';
let rowEl = document.getElementById('r' + y);
for (let x = 0; x < this.size; x++)
this.cells[x][y].addElement(rowEl);
}
}
}
class Cell {
constructor(x, y, mark) {
this.x = x;
this.y = y;
this.mark = mark;
this.id = 'c' + x + y;
this.element = null;
}
addElement(rowEl) {
rowEl.innerHTML += '<div id="' + this.id + '" class="board-cell"> CELL </div>';
this.element = document.getElementById(this.id);
this.element.addEventListener('click', () => this.clicked(), false);
}
clicked() {
console.log(this.x, this.y, ' CLICKED!');
}
}
window.onload = function () {
var game = new Board(3);
game.generate();
};
<style>
.board-cell {
width: 10%;
height: 10%;
background: white;
color:black;
}
</style>
<div id="container" class="fullscreen">
<div id="game" class="fullscreen">
<!-- Generated board -->
</div>
</div>
我知道我的代码现在一团糟,但是我很沮丧,这只是一个草图,我将继续研究。 另外,如果我犯了一些错误,请为我的英语感到抱歉。
答案 0 :(得分:0)
每次设置innerHTML
属性时,都会覆盖以前在此处设置的所有HTML。这包括串联分配,因为
element.innerHTML += '<b>Hello</b>';
与写作相同
element.innerHTML = element.innerHTML + '<b>Hello</b>';
这意味着所有未通过HTML属性附加的处理程序都将被“分离”,因为它们附加的元素不再存在,并且已替换了一组新元素。为了保留所有以前的事件处理程序,必须添加元素而不覆盖任何以前的HTML。最好的方法是使用DOM创建功能,例如createElement和appendChild:
let divEl = document.createElement("div");
divEl.innerHTML = "CELL";
divEl.className = 'board-cell'
divEl.id = this.id;
rowEl.appendChild(divEl);
行div元素也是如此:
let divRowEl = document.createElement("div");
divRowEl.className = 'board-row'
divRowEl.id = 'r' + y;
boardEl.appendChild(divRowEl);
class Board {
constructor(size) {
this.size = size;
this.cells = [];
for (let x = 0; x < size; x++) {
this.cells[x] = [];
for (let y = 0; y < size; y++) {
this.cells[x][y] = new Cell(x, y, null);
}
}
}
generate() {
document.getElementById('game').innerHTML = '<div id="board"></div>';
let boardEl = document.getElementById('board');
for (let y = 0; y < this.size; y++) {
let divRowEl = document.createElement("div");
divRowEl.className = 'board-row'
divRowEl.id = 'r' + y;
boardEl.appendChild(divRowEl);
let rowEl = document.getElementById('r' + y);
for (let x = 0; x < this.size; x++)
this.cells[x][y].addElement(rowEl);
}
}
}
class Cell {
constructor(x, y, mark) {
this.x = x;
this.y = y;
this.mark = mark;
this.id = 'c' + x + y;
this.element = null;
}
addElement(rowEl) {
let divEl = document.createElement("div");
divEl.innerHTML = "CELL" + this.id;
divEl.className = 'board-cell'
divEl.id = this.id;
divEl.addEventListener('click', () => this.clicked(), false);
rowEl.appendChild(divEl);
}
clicked() {
console.log(this.x, this.y, ' CLICKED!');
}
}
window.onload = function () {
var game = new Board(3);
game.generate();
};
<style>
.board-cell {
width: 10%;
height: 10%;
background: white;
color:black;
}
</style>
<div id="container" class="fullscreen">
<div id="game" class="fullscreen">
<!-- Generated board -->
</div>
</div>