我在努力学习Javascript。
我在Youtube上看了一些Javascript课程,并试图创建我的第一个项目。
项目应该是简单的抽搐-战术-脚趾游戏。
功能:第一次点击框应填写"X“,第二次单击另一个框时应填写"Y”,第三次单击另一个框时应再次填充"X“等,直到所有框都充满字符。
这是我的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="main">
<table>
<tr>
<td class="b1-1"></td>
<td class="b1-2"></td>
<td class="b1-3"></td>
</tr>
<tr>
<td class="b2-1"></td>
<td class="b2-2"></td>
<td class="b2-3"></td>
</tr>
<tr>
<td class="b3-1"></td>
<td class="b3-2"></td>
<td class="b3-3"></td>
</tr>
</table>
</div>
<script src="script.js" type="text/javascript"></script>
</body>
</html>CSS
.main {
padding: 100px 0;
width: 360px;
margin: 0 auto;
}
table, tbody {
margin: 0;
padding: 0;
width: 360px;
height: 360px;
}
tr {
width:360px;
height: 120px;
margin: 0;
padding: 0;
}
td {
text-align: center;
width:120px;
height: 120px;
border: 1px solid #333;
margin: 0;
padding: 0;
font-size: 50px;
}Javascript
var action = document.querySelectorAll('td');
var gameState = 0;
for (var i = 0; i <= action.length - 1; i++) {
getClassName = "." + action[i].classList.value;
if (gameState === 0) {
document.querySelector(getClassName).addEventListener("click", chasviX(i));
} else {
document.querySelector(getClassName).addEventListener("click", chasviO(i));
}
}
function chasviX(cord) {
document.querySelector("." + action[cord].classList.value).addEventListener("click", event => {
document.querySelector("." + action[cord].classList.value).textContent = "X";
gameState = 1;
});
};
function chasviO(cord) {
document.querySelector("." + action[cord].classList.value).addEventListener("click", event => {
document.querySelector("." + action[cord].classList.value).textContent = "O";
gameState = 0;
});
};还有项目链接- https://jsfiddle.net/qwy2k571/
此刻,每个盒子都装满了"X“。我知道我不完全理解闭包和作用域链,但是请给我一个正确的代码来理解它。
提前感谢并致以最良好的问候。
发布于 2020-02-19 13:57:55
在第一个循环:for (var i = 0; i <= action.length - 1; i++) { ... }中,您将向每个单元格添加事件侦听器。由于变量gameState被初始化为0,因此条件if (gameState === 0) { ... }在该循环中始终为真。
与其在初始化过程中检查游戏的状态,不如向每个单元格添加一个事件侦听器。
为了确保将正确的参数传递给事件,需要将回调包装在function() { chasvi(param); }中,并将整个循环体包装在另一个匿名函数中,将另一个变量设置为坐标i:
for (var i = 0; i <= action.length - 1; i++) {
(function(){
let coor = i;
let getClassName = "." + action[i].classList.value;
document.querySelector(getClassName).addEventListener("click", function() { chasvi(coor); });
}());
}请注意,我将函数的名称更改为chasvi,因为您可以在该函数中管理case、X或O。
在每个函数chasviX和chasviO中,您将再次添加一个事件侦听器。这是不好的,因为每次点击,您将添加多一个事件。
在点击之前,已经有一个事件了。
单击一次后,有两个事件。再点击一下,就会有3个事件,等等……
我建议您将这些函数更改为一个处理这两种情况的函数:
function chasvi(cord)
{
let TextToDisplay;
if (gameState === 0)
{
TextToDisplay = "X";
gameState = 1;
}
else
{
TextToDisplay = "O";
gameState = 0;
}
document.querySelector("." + action[cord].classList.value).textContent = TextToDisplay;
}因为gameState只有两个状态,所以可以使用一个布尔值。您可以将其初始化为var gameState = false;,我随机为X选择false。
然后,可以将该函数简化为:
function chasvi(cord)
{
let TextToDisplay;
if (gameState === false)
{
TextToDisplay = "X";
}
else
{
TextToDisplay = "O";
}
gameState = !gameState; // This swaps the state true/false
document.querySelector("." + action[cord].classList.value).textContent = TextToDisplay;
}这种表示法:
let TextToDisplay;
if (gameState === false)
{
TextToDisplay = "X";
}
else
{
TextToDisplay = "O";
}可以使用三元表达式简化:
let TextToDisplay = gameState ? "O" : "X"; // This means if gameState is true, then "O" is returned, else "X"最终代码可以如下所示:
var action = document.querySelectorAll('td');
var gameState = false;
for (var i = 0; i <= action.length - 1; i++) {
(function(){
let coor = i;
getClassName = "." + action[i].classList.value;
document.querySelector(getClassName).addEventListener("click", function() { chasvi(coor); });
}());
}
function chasvi(cord) {
let TextToDisplay = gameState ? "O" : "X";
gameState = !gameState;
document.querySelector("." + action[cord].classList.value).textContent = TextToDisplay;
}.main {
padding: 100px 0;
width: 360px;
margin: 0 auto;
}
table, tbody {
margin: 0;
padding: 0;
width: 360px;
height: 360px;
}
tr {
width:360px;
height: 120px;
margin: 0;
padding: 0;
}
td {
text-align: center;
width:120px;
height: 120px;
border: 1px solid #333;
margin: 0;
padding: 0;
font-size: 50px;
}<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="main">
<table>
<tr>
<td class="b1-1"></td>
<td class="b1-2"></td>
<td class="b1-3"></td>
</tr>
<tr>
<td class="b2-1"></td>
<td class="b2-2"></td>
<td class="b2-3"></td>
</tr>
<tr>
<td class="b3-1"></td>
<td class="b3-2"></td>
<td class="b3-3"></td>
</tr>
</table>
</div>
<script src="script.js" type="text/javascript"></script>
</body>
</html>
发布于 2020-02-19 13:28:21
由于您使用的是querySelectorAll,这将提供一个集合,因此您可以迭代该集合并直接向其添加事件侦听器。您正在添加多个事件侦听器,这不是必需的。
var action = document.querySelectorAll('td');
var gameState = 0;
action.forEach((item) => {
item.addEventListener('click', (e) => {
if (gameState === 0) {
e.target.textContent = "X";
gameState = 1;
} else {
e.target.textContent = "0";
gameState = 0;
}
})
}).main {
padding: 100px 0;
width: 360px;
margin: 0 auto;
}
table,
tbody {
margin: 0;
padding: 0;
width: 360px;
height: 360px;
}
tr {
width: 360px;
height: 120px;
margin: 0;
padding: 0;
}
td {
text-align: center;
width: 120px;
height: 120px;
border: 1px solid #333;
margin: 0;
padding: 0;
font-size: 50px;
}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<table>
<tr>
<td class="b1-1"></td>
<td class="b1-2"></td>
<td class="b1-3"></td>
</tr>
<tr>
<td class="b2-1"></td>
<td class="b2-2"></td>
<td class="b2-3"></td>
</tr>
<tr>
<td class="b3-1"></td>
<td class="b3-2"></td>
<td class="b3-3"></td>
</tr>
</table>
</div>
发布于 2020-02-19 13:37:23
在这里,我做了一个有用的动作:https://jsfiddle.net/1jnkepLg/1/
我将JS部分简化为:
var gameState = 0; // Holds the current game state
var cells = document.getElementsByTagName("td"); // list of cells of the game board
// attach an event listener at each cell.
for (var i=0;i<cells.length;i++)
{
cells[i].addEventListener("click", chasvi);
}
function chasvi()
{
// in event callbacks "this" refers to the element that triggered the event. In this case, it is the TD element.
this.textContent = gameState ? "X" : "0";
// switch the game state
gameState = !gameState;
}在这种情况下,一个事件侦听器就足够了,您可以确定要在回调函数中绘制什么X\0。
https://stackoverflow.com/questions/60301294
复制相似问题