前提: | 基本的計(jì)算機(jī)知識(shí),對(duì)HTML和CSS初步了解,知道JavaScript是什么。 |
---|---|
目標(biāo): | 擁有一點(diǎn)編寫JavaScript的經(jīng)驗(yàn),至少會(huì)獲得關(guān)于編寫JavaScript時(shí)應(yīng)當(dāng)涉及到些什么的基本認(rèn)識(shí)。 |
您不會(huì)被要求立即理解所有代碼的細(xì)節(jié)——現(xiàn)在我們只是想把高級(jí)概念介紹給您,以及給您一個(gè)JavaScript(以及其他編程語言)是如何工作的。在隨后的文章中,你將會(huì)再次看到這些功能的更多細(xì)節(jié)。
Note: 你在JavaScript中看到的許多代碼特性和其他編程語言類似— 函數(shù)、循環(huán),等等。 代碼語法看起來不同,但是在概念上是基本類似的。
在編程中學(xué)習(xí)的最困難的事情之一不是你需要學(xué)習(xí)的語法,而是如何應(yīng)用它來解決現(xiàn)實(shí)世界的問題。 你需要像一個(gè)程序員一樣開始思考 - 這通常涉及到對(duì)程序需要做什么的描述,以及如何實(shí)現(xiàn)這些東西需要什么代碼特性,以及如何使它們一起工作。
這需要努力工作,編程語法的經(jīng)驗(yàn)和實(shí)踐的混合,以及一點(diǎn)創(chuàng)造力。 你編寫的代碼越多,你就越好。 我們不能保證你將在5分鐘內(nèi)開發(fā)"程序員大腦",但我們將給你很多機(jī)會(huì)像整個(gè)課程中的程序員一樣練習(xí)思維。
考慮到這一點(diǎn),讓我們看看我們將在本文中構(gòu)建的示例,并查看將其分解為有形任務(wù)的一般過程。
在本文中,我們將向您展示如何構(gòu)建簡(jiǎn)單的游戲,您可以在下面看到:
<!DOCTYPE html> <html> <head> <meta 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> </head> <body> <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 less. 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"></p> <p class="lastResult"></p> <p class="lowOrHi"></p> </div> </body> <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; 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 = ''; } 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> </html>
有一個(gè)去玩它 - 熟悉游戲之前,你繼續(xù)前進(jìn)。
讓我們想象你的老板給你以下簡(jiǎn)要介紹創(chuàng)造這個(gè)游戲:
我想讓你創(chuàng)建一個(gè)可以猜數(shù)字的游戲,它會(huì)在1~100以內(nèi)隨機(jī)選擇一個(gè)數(shù), 然后讓玩家挑戰(zhàn)在10輪以內(nèi)猜出這個(gè)數(shù)字,每一輪都要告訴玩家正確或者錯(cuò)誤, 如果出錯(cuò)了,則告訴他數(shù)字是低了還是高了,并且還要告訴玩家之前猜的數(shù)字是什么。 一旦玩家猜測(cè)正確,或者他們用完了回合,游戲?qū)⒔Y(jié)束。 游戲結(jié)束后,可以讓玩家選擇再次開始。
看看這個(gè)簡(jiǎn)介,我們可以做的第一件事是開始把它分解成簡(jiǎn)單的可操作的任務(wù),盡可能多的程序員的心態(tài):
讓我們繼續(xù)前進(jìn),看看我們?nèi)绾螌⑦@些步驟轉(zhuǎn)換為代碼,構(gòu)建示例,以及探索JavaScript功能。
要開始本教程,我們希望您制作本地副本 number-guessing-game-start.html? 文件? (see it live here). 在文本編輯器和Web瀏覽器中打開它。 此時(shí),您將看到一個(gè)簡(jiǎn)單的標(biāo)題,用于輸入猜測(cè)的說明和形式段,但表單目前不會(huì)執(zhí)行任何操作。
我們將添加所有代碼的地方放在HTML底部的("script")元素中:
<script> // Your JavaScript goes here </script>
讓我們開始吧。 首先,在("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;
這部分代碼設(shè)置了我們需要存儲(chǔ)我們的程序?qū)⑹褂玫臄?shù)據(jù)的變量。 變量基本上是值的容器(例如數(shù)字或文本字符串)。 您可以使用關(guān)鍵字var以及變量的名稱創(chuàng)建一個(gè)變量。 然后,您可以使用等號(hào)(=)和您要賦予的值為變量賦值。
在我們的示例中:
<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">
Note: 稍后在課程中,您將學(xué)到更多關(guān)于變量的信息 , starting with the next article.
接下來,在您之前的JavaScript中添加以下內(nèi)容:
function checkGuess() { alert('I am a placeholder'); }
進(jìn)入 ?developer tools JavaScript console, 并輸入以下代碼:
checkGuess();
你應(yīng)該看到一個(gè)警報(bào),說"我是一個(gè)占位符"; 我們?cè)谖覀兊拇a中定義了一個(gè)函數(shù),在我們調(diào)用它時(shí)創(chuàng)建一個(gè)警報(bào)。
Note: 在課程后面你會(huì)學(xué)到更多關(guān)于函數(shù)的知識(shí)。
JavaScript運(yùn)算符允許我們執(zhí)行測(cè)試,做數(shù)學(xué),連接字符串在一起,和其他這樣的事情。
讓我們保存我們的代碼并刷新瀏覽器中顯示的頁面。 打開 developer tools JavaScript console 如果你還沒有打開已經(jīng)打開,所以你可以嘗試鍵入下面所示的示例 - 從"示例"列中輸入完全如圖所示,在每一個(gè)之后按Return / Enter,并查看他們返回的結(jié)果。 如果您無法輕松訪問瀏覽器開發(fā)人員工具,則可以隨時(shí)使用下面所示的簡(jiǎn)單內(nèi)置控制臺(tái):
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JavaScript console</title> <style> * { box-sizing: border-box; } html { background-color: #0C323D; color: #809089; font-family: monospace; } body { max-width: 700px; } p { margin: 0; width: 1%; padding: 0 1%; font-size: 16px; line-height: 1.5; float: left; } .input p { margin-right: 1%; } .output p { width: 100%; } .input input { width: 96%; float: left; border: none; font-size: 16px; line-height: 1.5; font-family: monospace; padding: 0; background: #0C323D; color: #809089; } div { clear: both; } </style> </head> <body> </body> <script> var geval = eval; function createInput() { var inputDiv = document.createElement('div'); var inputPara = document.createElement('p'); var inputForm = document.createElement('input'); inputDiv.setAttribute('class','input'); inputPara.textContent = '>'; inputDiv.appendChild(inputPara); inputDiv.appendChild(inputForm); document.body.appendChild(inputDiv); inputDiv.focus(); inputForm.addEventListener('change', executeCode); } function executeCode(e) { try { var result = geval(e.target.value); } catch(e) { var result = 'error — ' + e.message; } var outputDiv = document.createElement('div'); var outputPara = document.createElement('p'); outputDiv.setAttribute('class','output'); outputPara.textContent = 'Result: ' + result; outputDiv.appendChild(outputPara); document.body.appendChild(outputDiv); e.target.disabled = true; e.target.parentNode.style.opacity = '0.5'; createInput() } createInput(); </script> </html>
首先讓我們來看看算術(shù)運(yùn)算符,例如:
操作員 | 名稱 | 例子 |
---|---|---|
+ |
Addition | 6 + 9 |
- |
Subtraction | 20 - 15 |
* |
Multiplication | 3 * 7 |
/ |
Division | 10 / 5 |
您也可以使用+運(yùn)算符將文本字符串連接在一起(在編程中稱為連接)。 嘗試輸入以下行:
var name = 'Bingo'; name; var hello = ' says hello!'; hello; var greeting = name + hello; greeting;
還有一些快捷操作符可用,稱為增強(qiáng)賦值操作符。 例如,如果你想簡(jiǎn)單地添加一個(gè)新的文本字符串到一個(gè)現(xiàn)有的并返回結(jié)果,你可以這樣做:
name += ' says hello!';
這相當(dāng)于
name = name + ' says hello!';
當(dāng)我們運(yùn)行true / false測(cè)試(例如在條件語句 - 見下面),我們使用比較運(yùn)算符,例如:
操作員 | 名稱 | 例子 |
---|---|---|
=== |
嚴(yán)格的平等(是完全一樣嗎?) | 5 === 2 + 4 |
!== |
不平等(是不是相同?) | 'Chris' !== 'Ch' + 'ris' |
< |
少于 | 10 < 6 |
> |
比...更棒 | 10 > 20 |
回到我們的checkGuess()函數(shù),我認(rèn)為可以說,我們不希望它只是吐出一個(gè)占位符消息。 我們希望它能夠檢查玩家的猜測(cè)是否正確,并做出適當(dāng)?shù)姆磻?yīng)。
此時(shí),將您當(dāng)前的checkGuess()函數(shù)替換為此版本:
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(); }
這是很多代碼 - phew! 讓我們通過每個(gè)部分,并解釋它做什么。
guessCount === 1如果是, 我們讓 guesses 段落的文本內(nèi)容等于"Previous guesses: "。如果不是,就算了。
else if(){ }
structure.它會(huì)檢查這個(gè)回合是否是用戶最后一個(gè)回合。如果是,程序回合前面一樣,除了把祝賀信息換成一個(gè)game over信息。else { }
) contains code that is only run if neither of the other two tests returns true (i.e. the player didn't guess right, but they have more guesses left). In this case we tell them they are wrong, then we perform another conditional test to check whether the guess was higher or lower than the answer, displaying a further message as appropriate to tell them higher or lower.guessCount
variable so the player uses up their turn (++
is an incrementation operation — increment by 1), and empty the value out of the form text field and focus it again, ready for the next guess to be entered.在這一點(diǎn)上,我們有一個(gè)很好的實(shí)現(xiàn)checkGuess()函數(shù),但它不會(huì)做任何事情,因?yàn)槲覀冞€沒有調(diào)用它。 理想情況下,我們希望在按下"提交猜測(cè)"按鈕時(shí)調(diào)用它,為此,我們需要使用事件。 事件是瀏覽器中發(fā)生的操作,例如點(diǎn)擊按鈕,加載頁面或播放視頻,我們可以運(yùn)行代碼塊來響應(yīng)。 偵聽事件發(fā)生的構(gòu)造稱為事件偵聽器,并且響應(yīng)于事件觸發(fā)而運(yùn)行的代碼塊被稱為事件處理器。
在checkGuess()函數(shù)的結(jié)束大括號(hào)下面添加以下代碼:
guessSubmit.addEventListener('click', checkGuess);
這里我們?yōu)間uessSubmit按鈕添加了一個(gè)監(jiān)聽事件。這個(gè)方法 包含兩個(gè)可輸入值(參數(shù)),監(jiān)聽事件的類型(在本例中為"點(diǎn)擊"),和當(dāng)事件發(fā)生時(shí)我們想要執(zhí)行的代碼(在本例中為checkGuess()函數(shù))——注意,當(dāng)函數(shù)作為事件監(jiān)聽方法的參數(shù)時(shí),函數(shù)名后不應(yīng)帶括號(hào)。
嘗試保存和刷新您的代碼現(xiàn)在,您的示例應(yīng)該現(xiàn)在工作,一點(diǎn)。 現(xiàn)在唯一的問題是,如果你猜到正確的答案或運(yùn)行猜測(cè),游戲?qū)⒋蚱?,因?yàn)槲覀冞€沒有定義setGameOver()函數(shù),應(yīng)該在游戲結(jié)束后運(yùn)行。 讓我們現(xiàn)在添加我們?nèi)鄙俚拇a,并完成示例功能。
讓我們將setGameOver()函數(shù)添加到我們的代碼底部,然后遍歷它。 現(xiàn)在添加,在其余的JavaScript下面:
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); }
現(xiàn)在我們需要定義這個(gè)函數(shù)了! 將以下代碼添加到JavaScript的底部:
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; }
這個(gè)相當(dāng)長的代碼塊完全重置了一切:
在這一點(diǎn)上,你應(yīng)該有一個(gè)完全工作(簡(jiǎn)單)的游戲 。
我們現(xiàn)在在本文中仍然要做的是談?wù)撘恍┢渌匾拇a功能,你已經(jīng)看到,雖然你可能沒有意識(shí)到這一點(diǎn)。
上面代碼的一部分,我們需要更詳細(xì)地看一下 for 循環(huán)。 循環(huán)在編程中是一個(gè)非常重要的概念,它允許你一直重復(fù)運(yùn)行一段代碼,直到滿足某個(gè)條件。
首先,請(qǐng)?jiān)俅无D(zhuǎn)到 瀏覽器開發(fā)工具 JavaScript 控制臺(tái)然后輸入以下內(nèi)容:
for (var i = 1 ; i < 21 ; i++) { console.log(i) }
發(fā)生了什么? 數(shù)字1到20在控制臺(tái)中打印出來。 這是因?yàn)檠h(huán)。 for循環(huán)需要三個(gè)輸入值(參數(shù)):
現(xiàn)在讓我們看看我們的猜測(cè)游戲循環(huán) - 以下可以在resetGame()函數(shù)中找到:
var resetParas = document.querySelectorAll('.resultParas p'); for (var i = 0 ; i < resetParas.length ; i++) { resetParas[i].textContent = ''; }
此代碼在<div class="resultparas">內(nèi)使用queryselectorall()方法創(chuàng)建一個(gè)變量包含一個(gè)列表中的所有段落,然后依次通過每個(gè)段落,刪除每個(gè)段落的文本內(nèi)容。
讓我們?cè)賮硪淮巫詈蟮母倪M(jìn),然后再討論。 在var resetButton下面添加以下行: 行靠近JavaScript的頂部,然后保存您的文件:
guessField.focus();
這一行使用focus()
方法立即自動(dòng)地放置文本光標(biāo)在輸入框內(nèi),當(dāng)頁面加載完成時(shí),意味著用戶可以馬上開始他們的第一次游戲,而不需要去點(diǎn)擊輸入框。 這只是一個(gè)小的附加,但它提高了可用性 ——?給用戶提供了可視化的線索去告訴他們?cè)撛趺撮_始這個(gè)游戲。
讓我們分析一下在這里有更多的細(xì)節(jié)。在JavaScript中,一切都是一個(gè)對(duì)象。對(duì)象是存儲(chǔ)在單個(gè)分組中的相關(guān)功能的集合。你可以創(chuàng)建自己的對(duì)象,但這是相當(dāng)先進(jìn)的,我們不會(huì)覆蓋它,直到很晚以后的課程。現(xiàn)在,我們將簡(jiǎn)要討論您的瀏覽器包含的內(nèi)置對(duì)象,它允許您做許多有用的事情。
在這種特殊情況下,我們首先創(chuàng)建了一個(gè)guessField變量,用于存儲(chǔ)對(duì)HTML中的文本輸入表單字段的引用 - 在頂部附近的變量聲明中可以找到以下行:
var guessField = document.querySelector('.guessField');
我們使用了document對(duì)象的querySelector()方法來獲得此引用。querySelector()?需要一條信息?— — 用該元素的?CSS?選擇器選擇你想要的引用的元素。
因?yàn)?guessField?現(xiàn)在包含對(duì)?<input>的元素的引用,它現(xiàn)在將訪問數(shù)量的屬性?(存儲(chǔ)于內(nèi)部對(duì)象的其中一些不會(huì)更改其值的基礎(chǔ)變量)?和方法?(存儲(chǔ)在對(duì)象內(nèi)部的基礎(chǔ)函數(shù))。一種方法可用來輸入元素是?focus (),所以我們現(xiàn)在可以使用這條線集中文本輸入︰
guessField.focus();
不包含對(duì)表單元素引用的變量不會(huì)有?focus () 方法可供它們執(zhí)行。例如,guesses變量包含對(duì)?<p>元素的引用和?guessCount?包含了一個(gè)數(shù)字。
讓我們使用一些瀏覽器對(duì)象。
guessField
and the console will show you that the variable contains an <input>
element. You'll also notice that the console autocompletes object names that exist inside the execution environment, including your variables!guessField.value = 'Hello';The
value
property represents the current value entered into the text field. You'll see that by entering this command, we've changed what that is!guesses
and pressing return. The console will show you that the variable contains a <p>
element.guesses.valueThe browser will return
undefined
, because value
doesn't exist on paragraphs.textContent
property instead. Try this:
guesses.textContent = 'Where is my paragraph?';
guesses.style.backgroundColor = 'yellow'; guesses.style.fontSize = '200%'; guesses.style.padding = '10px'; guesses.style.boxShadow = '3px 3px 6px black';
所以這是為了建立這個(gè)例子— 你得到了結(jié)束,做得好! 嘗試你的最終代碼,或者看看我們的版本.如果你不能讓示例工作,請(qǐng)檢查它 source code.
更多建議: