JavaScript学习笔记一
1.猜数字游戏
1.1 要求:设计一个猜数游戏
在1~100以内随机选择一个数, 然后让玩家挑战在10轮以内猜出这个数字,每一轮都要告诉玩家正确或者错误, 如果出错了,则告诉他数字是低了还是高了,并且还要告诉玩家之前猜的数字是什么。 一旦玩家猜测正确,或者他们用完了回合,游戏将结束。 游戏结束后,可以让玩家选择再次开始。
1.2 从程序员的思维思考
生成1到100之间的随机数。
记录玩家在第几轮。从1开始。
为玩家提供一种猜测数字的方法。
一旦提交了猜测,首先将它记录在某处,以便用户可以看到他们先前的猜测。
接下来检查它是否是正确的数字。
如果是正确的:
- 显示祝贺消息。
- 阻止玩家输入更多的猜测(这会使游戏混乱)。
- 显示控制允许玩家重新开始游戏。
如果它错了,并且玩家有剩余轮次:
- 告诉玩家他们错了。
- 允许他们输入另一个猜测。
- 将圈数增加1。
如果它是错误的,并且玩家没有剩余轮次:
- 告诉玩家游戏结束。
- 阻止玩家输入更多的猜测(这会使游戏混乱)。
- 显示控制允许玩家重新开始游戏。
一旦游戏重新启动,请确保游戏逻辑和用户界面完全重置,然后返回步骤1。
1.3 将思路转化为代码
1.3.1 初始设置
建立一个简单的表单,用于输入猜测的说明和形式段,如图:
1.3.2 添加变量以保存数据
<script>
var randomNumber = Math.floor(Math.random() * 100) + 1;
var guesses = document.querySelector('.guesses');
var lastResult = document.querySelector('.lastResult');
var lowOrHi = document.querySelector('.lowOrHi');
var guessSubmit = document.querySelector('.guessSubmit');
var guessField = document.querySelector('.guessField');
var guessCount = 1;
var resetButton;
</script>
这部分代码设置了存储程序将使用的数据的变量。 变量基本上是值(例如数字或文本字符串)的容器。
可以使用关键字var
以及变量的名称创建一个变量。 然后可以使用等号(=)和您要赋予的值为变量赋值。
在上面的示例中:
第一个变量
randomNumber
被分配一个1到100之间的随机数,使用数学算法计算。接下来三个变量都用于存储对HTML中的结果段落的引用,并用于在代码的后面段落中插入值:
<p class="guesses"></p> <p class="lastResult"></p> <p class="lowOrHi"></p>
接下来的两个变量存储对表单文本输入和提交按钮的引用,并用于控制以后提交猜测:
<label for="guessField">Enter a guess: </label><input type="text" id="guessField" class="guessField"> <input type="submit" value="Submit guess" class="guessSubmit">
最后两个变量存储一个猜测计数1(用于跟踪玩家有多少猜测),以及一个不存在的引用(但稍后会有)。
1.3.3 函数
一个小例子:
function checkGuess() {
alert('I am a placeholder');
}
函数是可重复使用的代码块,可以“编写一次,到处运行”,从而节省了大量的重复代码, 有许多方法来定义函数,但现在我们先将注意力集中在当前这个简单的方式上。 这里我们使用关键字function
定义了一个函数,后面跟着一个名字,再后面加了括号。 之后,我们放两个大括号({}
)。 在大括号里面,放置着当调用该函数时所有想要运行的代码。
1.3.4 运算符
1.3.5 条件
新的checkGuess()
函数:
function checkGuess() {
var userGuess = Number(guessField.value);
if (guessCount === 1) {
guesses.textContent = 'Previous guesses: ';
}
guesses.textContent += userGuess + ' ';
if (userGuess === randomNumber) {
lastResult.textContent = 'Congratulations! You got it right!';
lastResult.style.backgroundColor = 'green';
lowOrHi.textContent = '';
setGameOver();
} else if (guessCount === 10) {
lastResult.textContent = '!!!GAME OVER!!!';
setGameOver();
} else {
lastResult.textContent = 'Wrong!';
lastResult.style.backgroundColor = 'red';
if(userGuess < randomNumber) {
lowOrHi.textContent = 'Last guess was too low!';
} else if(userGuess > randomNumber) {
lowOrHi.textContent = 'Last guess was too high!';
}
}
guessCount++;
guessField.value = '';
guessField.focus();
}
这段代码的意图:
- 第一行(上面的第2行)声明了一个名为
userGuess
的变量,并将其值设置为在文本字段中输入的当前值。 还通过内置的Number()方法运行这个值,只是为了确保该值绝对是一个数字。 - 条件代码块(上面的3 - 5行)。 在括号内包含了一个比较。 如果比较返回true,就会执行放在花括号中的代码。 反之,花括号中的代码就会被跳过,从而执行下一行代码。 在这种情况下,比较是测试
guessCount
变量是否等于1,即玩家是不是第一次猜数字:guessCount === 1
如果是, 让guesses段落的文本内容等于”Previous guesses: “。如果不是,那就说明我们已经执行过了文本设定,那就无需再次设定了。 - 第6行将当前
userGuess
值附加到guesses段落的末尾,并加上一个空格,因此在每个猜测值之间将有一个空格。 下一个代码块中(上面的第8-24行)做了几个检查:
- 第一个if(){ }检查用户的猜测是否等于在代码顶端设置的randomNumber值。如果是,则玩家猜对了,游戏胜利,我们将向玩家显示一个漂亮的绿色的祝贺信息,并清除猜测信息框的内容,调用setGameOver()方法。
- 紧接着我们又写了一个else if(){ } 结构。它会检查这个回合是否是玩家的最后一个回合。如果是,程序将做与前一个程序块相同的事情,除了它显示的是Game Over而不是祝贺消息。
- 最后的一个块是else { },其中包含着前面两个比较都为false才会执行的代码,即玩家还有游戏的次数但是本次没猜对。在这个情况下,我们会告诉玩家他们猜错了,并执行一个条件测试,判断并告诉玩家猜测的数字是大是小。
这个函数最后三行 (上面的第26–28行) 让我们为下次猜测值提交做好准备。我们把guessCount变量的值+1,因此玩家消耗了一次机会 (++是一个递增操作符 - 将值+1),然后我们把文本段的值清空,重新将焦点设置在文本段里,准备下一轮游戏。
1.3.6 事件
现在,checkGuess()函数已经实现大部分功能了,但它现在不会做任何事情,因为还没有调用它。
理想情况是,我们希望在按下“Submit guess”按钮时调用它,为此,我们需要使用事件。
事件是浏览器中发生的动作,例如点击按钮,加载页面或播放视频,我们可以调用代码来响应。
侦听事件发生的构造方法称为事件监听器,响应事件触发而运行的代码块被称为事件处理器。
在checkGuess()函数的结束大括号后添加以下代码:
guessSubmit.addEventListener('click', checkGuess);
这里为guessSubmit按钮添加了一个监听事件。这个方法包含两个可输入值(参数),监听事件的类型(在本例中为“点击”),和当事件发生时我们想要执行的代码(在本例中为checkGuess()函数)——注意,当函数作为事件监听方法的参数时,函数名后不应带括号。
保存代码并刷新页面,示例某些功能现在应该能正常工作了。 现在唯一的问题是,如果猜到正确的答案或游戏次数已使用完,游戏将发生错乱,因为我们还没有定义应该在游戏结束后运行的setGameOver()函数。
1.3.7 进一步完善游戏
将setGameOver()函数添加到代码底部,然后再来观察它:
function setGameOver() {
guessField.disabled = true;
guessSubmit.disabled = true;
resetButton = document.createElement('button');
resetButton.textContent = 'Start new game';
document.body.appendChild(resetButton);
resetButton.addEventListener('click', resetGame);
}
前两行禁用表单文本输入和按钮,方法是将其disable属性设置为true。 这是有必要的,如果没有禁用,用户可以在游戏结束后提交更多的猜测,这会破坏游戏的规则。
接下来的三行创建了一个新的button元素,设置它的文本为“Start new game”,并把它添加到我们文档的底部。
- 最后一行在新按钮上设置了一个事件监听器,当它被点击时,一个名为resetGame()的函数被将被调用。
resetGame()函数。将以下代码添加到代码底部:
function resetGame() {
guessCount = 1;
var resetParas = document.querySelectorAll('.resultParas p');
for (var i = 0 ; i < resetParas.length ; i++) {
resetParas[i].textContent = '';
}
resetButton.parentNode.removeChild(resetButton);
guessField.disabled = false;
guessSubmit.disabled = false;
guessField.value = '';
guessField.focus();
lastResult.style.backgroundColor = 'white';
randomNumber = Math.floor(Math.random() * 100) + 1;
}
这个代码块完全重置了一切:
- 将guessCount重置为1。
- 清除所有信息段落。
- 从代码中删除重置按钮。
- 启用表单元素,并清空和聚焦文本字段,准备接受用户输入的新猜测。
- 从lastResult段中删除背景颜色。
- 生成一个新的随机数,这样下次就是在猜测新的数字了!
现在,一个能完整工作的(简单)游戏就完成了。
接下来来讨论下其他很重要的代码功能。
1.3.8 一些关于函数的事
让我们再来一次最后的改进,然后再讨论。 在var resetButton
下面添加以下行,行靠近JavaScript的顶部,然后保存的文件:
guessField.focus();
这一行使用focus()
方法立即自动地放置文本光标在输入框内,这意味着当页面加载完成时,用户可以马上开始他们的第一次游戏,而不需要去点击输入框。 这只是一个小的改进,但它提高了可用性 —— 给用户提供了可视化的线索去告诉他们该怎么开始这个游戏。
让我们分析一下在这里有更多的细节。在JavaScript中,一切都是对象。
对象是存储在单个分组中的相关功能的集合。
在这种特殊情况下,我们首先创建了一个guessField变量,用于存储对HTML中的文本输入表单字段的引用 - 在顶部附近的变量声明中可以找到以下行:
var guessField = document.querySelector('.guessField');
这里使用了document对象的querySelector()方法来获得此引用。querySelector()需要一个参数 — — 用该元素的 CSS 选择器选择您想要的引用的元素。
因为guessField现在包含对<input>
的元素的引用,它现在将访问数量的属性 (存储于内部对象的其中一些不会更改其值的基础变量) 和方法 (存储在对象内部的基础函数)。一种方法可用来输入元素是focus(),所以我们现在可以使用这条线集中文本输入︰
guessField.focus();
不包含对表单元素引用的变量不会有focus()方法供它们执行。例如,包含对
元素的引用的guesses变量和包含了一个数字的guessCount变量。
1.4 源代码
<!DOCTYPE html>
<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Number guessing game</title>
<style>
html {
font-family: sans-serif;
}
body {
width: 50%;
max-width: 800px;
min-width: 480px;
margin: 0 auto;
}
.lastResult {
color: white;
padding: 3px;
}
</style>
<style type="text/css" abt="234"></style>
</head>
<body data-gr-c-s-loaded="true">
<h1>Number guessing game</h1>
<p>We have selected a random number between 1 and 100. See if you can guess it in 10 turns or fewer. We'll tell you if your guess was too high or too low.</p>
<div class="form">
<label for="guessField">Enter a guess: </label><input type="text" id="guessField" class="guessField">
<input type="submit" value="Submit guess" class="guessSubmit">
</div>
<div class="resultParas">
<p class="guesses">Previous guesses: 10 </p>
<p class="lastResult" style="background-color: red;">Wrong!</p>
<p class="lowOrHi">Last guess was too high!</p>
</div>
<script>
// Your JavaScript goes here
var randomNumber = Math.floor(Math.random() * 100) + 1;
var guesses = document.querySelector('.guesses');
var lastResult = document.querySelector('.lastResult');
var lowOrHi = document.querySelector('.lowOrHi');
var guessSubmit = document.querySelector('.guessSubmit');
var guessField = document.querySelector('.guessField');
var guessCount = 1;
var resetButton;
guessField.focus();
function checkGuess() {
var userGuess = Number(guessField.value);
if(guessCount === 1) {
guesses.textContent = 'Previous guesses: ';
}
guesses.textContent += userGuess + ' ';
if(userGuess === randomNumber) {
lastResult.textContent = 'Congratulations! You got it right!';
lastResult.style.backgroundColor = 'green';
lowOrHi.textContent = '';
setGameOver();
} else if(guessCount === 10) {
lastResult.textContent = '!!!GAME OVER!!!';
lowOrHi.textContent = '';
setGameOver();
} else {
lastResult.textContent = 'Wrong!';
lastResult.style.backgroundColor = 'red';
if(userGuess < randomNumber) {
lowOrHi.textContent = 'Last guess was too low!';
} else if(userGuess > randomNumber) {
lowOrHi.textContent = 'Last guess was too high!';
}
}
guessCount++;
guessField.value = '';
guessField.focus();
}
guessSubmit.addEventListener('click', checkGuess);
function setGameOver() {
guessField.disabled = true;
guessSubmit.disabled = true;
resetButton = document.createElement('button');
resetButton.textContent = 'Start new game';
document.body.appendChild(resetButton);
resetButton.addEventListener('click', resetGame);
}
function resetGame() {
guessCount = 1;
var resetParas = document.querySelectorAll('.resultParas p');
for(var i = 0 ; i < resetParas.length ; i++) {
resetParas[i].textContent = '';
}
resetButton.parentNode.removeChild(resetButton);
guessField.disabled = false;
guessSubmit.disabled = false;
guessField.value = '';
guessField.focus();
lastResult.style.backgroundColor = 'white';
randomNumber = Math.floor(Math.random() * 100) + 1;
}
</script>
</body>
</html>