μ«μ μΌκ΅¬(Number Baseball) κ²μ ꡬν μλ£
μΉ μλ² / μλ²μ ν΄λΌμ΄μΈνΈ / μΉ νΈμ€ν / Ajax / fetch API / 리ν©ν λ§ ν¨μ
μνμ½λ© μΉ μλ² κ°μ (μλ²μ ν΄λΌμ΄μΈνΈ / μΉ νΈμ€ν )
μνμ½λ© 2018 Ajax κ°μ 1 ~ 10νΈ
μ΄μ νμ΄μμ μ΄μ΄μ
μ¬μ©μκ° 10νκΉμ§ μλν μ μλλ‘ μ νν©λλ€.
removeEventListener('μ κ±°ν μ΄λ²€νΈ 리μ€λμ μ΄λ²€νΈ νμ
', μ κ±°ν μ΄λ²€νΈ 리μ€λ ν¨μ μ΄λ¦);
μ΄λ²€νΈ 리μ€λ λ°μ
, click λ³μλ₯Ό μ μΈνκ³ 0μ ν λΉν¨
μ΄λ²€νΈ 리μ€λ μμ, click++ λ₯Ό μΆκ°ν¨
clickμ΄ 10μ΄ λλ©΄, μ΄λ²€νΈ 리μ€λκ° μμ λλλ‘ ν¨
const enter = document.querySelector('.box-field-enter');
const userString = document.querySelector('#box-field-input');
const result = document.querySelector('.box-result');
let click = 0; // λ°λμ μ΄λ²€νΈ 리μ€λ λ°μ μ μ΄μ€μΌ ν¨
enter.addEventListener('click', function clickEnter () {
const random = hidden.innerText;
const user = userString.value;
// (μ½λ μ€λ΅)
const strikeCount = array.filter(e => e === 'strike').length;
const ballCount = array.filter(e => e === 'ball').length;
if (user.length !== 3) {
alert('μΈ μ리 μ«μλ₯Ό μ
λ ₯ν΄μΌ ν©λλ€.');
} else if (user.length === 3) {
result.innerText = `${strikeCount} strike ${ballCount} ball`;
}
// ENTERλ₯Ό λλ₯Ό λλ§λ€ clickμ ν λΉλ μ«μκ° 1μ© μ¦κ°
click++;
// clickμ΄ 10μ΄ λλ©΄ μ΄λ²€νΈ 리μ€λ μμ
if (click === 10) {
enter.removeEventListener('click', clickEnter);
}
});
κ²μ μ¬μμ λ²νΌμ λ§λ€κ³ , μ¬μμ ν μ μλλ‘ ν©λλ€.
ν΄λΉ λ²νΌμ κ°μΈκ³ μλ < form ></ form > μμ μλ μ¬μ©μ μ λ ₯ κ°λ€μ μ΄κΈ°ννλ€
π HTML
RESTART λ²νΌμ typeμ resetμΌλ‘ μ§μ
form νκ·Έ μμΉ μμ
<body>
<section>
<!-- μΌκ΅¬κ²μ Start -->
<div class="box">
<button class="box-start">START</button>
<form class="box-field">
<label for="box-field-input">μ«μ μ
λ ₯ μΉΈ : </label>
<input type="number" placeholder="μΈ μ리 μ«μ μ
λ ₯" id="box-field-input">
<button type="button" class="box-field-enter">ENTER</button>
<div class="box-result"></div>
<button type="reset" class="box-restart">RESTART</button>
</form>
</div>
<!-- μΌκ΅¬κ²μ End -->
</section>
</body>
π javascript
// κ²μ μ¬μμ λ²νΌ
const restart = document.querySelector('.box-restart');
restart.addEventListener('click', function () {
result.innerText = '';
});
μꡬ μ¬νμ λͺ¨λ ꡬνμ μλ£νλ€
κ·Έλ°λ° ν μ€νΈλ₯Ό ν΄λ³΄λ€ μλν λλ‘ μ€νλμ§ μλ λΆλΆμ λ°κ²¬ν¨
μ¬μ©μκ° μΈ μ리 μ«μλ₯Ό μ λ ₯νμ κ²½μ°μλ§ click++μ΄ μ§νλλλ‘ click++μ μμΉλ₯Ό else if ꡬ문 μμΌλ‘ μ΄λμν΄
λ§μ°¬κ°μ§λ‘ clickμ΄ 10μ΄ λμ λ μ΄λ²€νΈ 리μ€λλ₯Ό μ κ±°νλ ꡬ문λ else if ꡬ문 μμΌλ‘ μ΄λμν΄
if (user.length !== 3) {
alert('μΈ μ리 μ«μλ₯Ό μ
λ ₯ν΄μΌ ν©λλ€.');
} else if (user.length === 3) {
result.innerText = `${strikeCount} strike ${ballCount} ball`;
click++;
if (click === 10) {
enter.removeEventListener('click', clickEnter);
}
}
<html>
<body>
<section>
<div class="box">
<button class="box-start">START</button>
<form class="box-field">
<label for="box-field-input">μ«μ μ
λ ₯ μΉΈ : </label>
<input type="number" placeholder="μΈ μ리 μ«μ μ
λ ₯" id="box-field-input">
<button type="button" class="box-field-enter">ENTER</button>
<div class="box-result"></div>
<button type="reset" class="box-restart">RESTART</button>
</form>
</div>
</section>
<p class="hidden"></p>
</body>
</html>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
button {
border: 1px solid black;
background: transparent;
cursor: pointer;
border-radius: 5px;
background-color: white;
}
body {
padding: 80px;
}
section {
max-width: 1000px;
margin: 0 auto;
}
.box {
text-align: center;
margin: 40px;
padding: 40px;
border: 2px solid black;
border-radius: 5px;
}
.box-start {
margin: 20px;
padding: 10px 20px;
}
.box-field {
margin: 20px;
}
.box-field-enter {
margin: 20px;
padding: 3px 10px;
}
.box-result {
border: 1px solid black;
border-radius: 5px;
background-color: white;
height: 100px;
margin: 40px;
line-height: 5;
}
.box-restart {
margin-bottom: 20px;
padding: 10px 20px;
}
.hidden {
display: none;
}
'use strict';
// 1. κ²μ μμ λ²νΌ - λλ€ν μΈ μ리 μ«μ (보μ΄μ§ μκ²)
const start = document.querySelector('.box-start');
const hidden = document.querySelector('.hidden');
start.addEventListener('click', function () {
const naturalOne = Math.floor((Math.random() * (10 - 0)) + 0);
const naturalTwo = Math.floor((Math.random() * (10 - 0)) + 0);
const naturalThree = Math.floor((Math.random() * (10 - 0)) + 0);
const randomString = `${naturalOne}${naturalTwo}${naturalThree}`;
hidden.innerText = randomString;
});
// 2. μν° ν€ - μΈ μ리 μ«μ x, κ²½κ³ μ°½
// 3. μν° ν€ - 'λλ€ μ«μ' vs 'μ
λ ₯ κ°' λΉκ΅, λ³Ό/μ€νΈλΌμ΄ν¬ μΆλ ₯
// 4. μ¬μ©μκ° 10νκΉμ§ μλν μ μλλ‘ μ ν
// 6. μΈ μ리 μ«μ μ
λ ₯ μμλ§ 10νμ ν¬ν¨λλλ‘
const enter = document.querySelector('.box-field-enter');
const userString = document.querySelector('#box-field-input');
const result = document.querySelector('.box-result');
let click = 0;
enter.addEventListener('click', function clickEnter () {
// hidden.innerText(λλ€ μ«μ)λ string
// userString.value(μ¬μ©μ μ
λ ₯ κ°)λ string
const random = hidden.innerText;
const user = userString.value;
const a = Number(random[0]);
const b = Number(random[1]);
const c = Number(random[2]);
const x = Number(user[0]);
const y = Number(user[1]);
const z = Number(user[2]);
function compareAX () {
if (a === x) {
return 'strike';
}
}
function compareAY () {
if (a === y) {
return 'ball';
}
}
function compareAZ () {
if (a === z) {
return 'ball';
}
}
function compareBX () {
if (b === x) {
return 'ball';
}
}
function compareBY () {
if (b === y) {
return 'strike';
}
}
function compareBZ () {
if (b === z) {
return 'ball';
}
}
function compareCX () {
if (c === x) {
return 'ball';
}
}
function compareCY () {
if (c === y) {
return 'ball';
}
}
function compareCZ () {
if (c === z) {
return 'strike';
}
}
const array = [compareAX(), compareAY(), compareAZ(), compareBX(), compareBY(), compareBZ(), compareCX(), compareCY(), compareCZ()];
const strikeCount = array.filter(e => e === 'strike').length;
const ballCount = array.filter(e => e === 'ball').length;
if (user.length !== 3) {
alert('μΈ μ리 μ«μλ₯Ό μ
λ ₯ν΄μΌ ν©λλ€.');
} else if (user.length === 3) {
result.innerText = `${strikeCount} strike ${ballCount} ball`;
click++;
if (click === 10) {
enter.removeEventListener('click', clickEnter);
}
}
});
// 5. κ²μ μ¬μμ λ²νΌ
const restart = document.querySelector('.box-restart');
restart.addEventListener('click', function () {
result.innerText = '';
});
μνμ½λ© μΉ μλ² κ°μ μ°Έκ³
ν΄λΌμ΄μΈνΈ(client) : μ 보λ₯Ό μμ²νλ μ»΄ν¨ν° (μΉ/κ²μ/μ±ν ν΄λΌμ΄μΈνΈ λ±)
μλ²(server) : μ 보λ₯Ό μλ΅νλ μ»΄ν¨ν° (μΉ/κ²μ/μ±ν μλ² λ±)
κΉνλΈμμ μ§μνλ μΉ νΈμ€ν μλΉμ€ μ΄μ©
publicμΌλ‘ repository λ§λ€κΈ°
repositoryμμ Setting λ©λ΄μ GitHub Pages ν΄λ¦
sourceμμ Branch: main λλ master μ ν ν save
λ°λ‘ μμ μμ±λ μ£Όμ ν΄λ¦νκΈ°
404 errorκ° λ¨λ©΄ μ‘°κΈ κΈ°λ€λ¦° ν μλ‘κ³ μΉ¨ ν΄λ³΄κ±°λ ν μ£Όμ λ€μ html νμΌ μ΄λ¦ λΆμ¬ λ£κ³ μν° λλ₯΄κΈ°
μνμ½λ© 2018 Ajax κ°μ (1 ~ 10νΈ) μ°Έκ³
μΉ νμ΄μ§λ₯Ό λΆλΆμ μΌλ‘ κ°±μ
ν μ μλλ‘ ν΄μ€λ€
ex. μ¬μ΄νΈ λ΄ λͺ¨λ νμ΄μ§μ μΉ΄ν κ³ λ¦¬ κΈ°νΈλ₯Ό < ol >μμ < ul >λ‘ λ³κ²½νκ³ μΆμ κ²½μ°, κΈ°λ³Έ index.htmlλ§ μμ ν΄μ€λ ajaxλ₯Ό μ΄μ©ν΄ λμ μΌλ‘ λͺ¨λ νμ΄μ§μ μΉ΄ν κ³ λ¦¬ κΈ°νΈ λ³κ²½ κ°λ₯
μ΄λ₯Ό ν΅ν΄ νλμ νμ΄μ§μμ μ¬λ¬ μ 보λ€μ ννν μ μλ, single-page application
μ ꡬνν μ μλ€
(μμλ₯Ό λ€μ΄ μ€λͺ )
Ajaxλ₯Ό μ΄μ©νλ©΄,
λ©λ΄λ₯Ό ν΄λ¦νμ λ
μΉ νμ΄μ§λ₯Ό reload νμ§ μκ³
νμ΄μ§μ μΌμ λΆλΆ
λ§μ μΉ λΈλΌμ°μ κ° μΉ μλ²μ μμ²ν΄ κ°μ Έμμ νλ©΄μ νμνλλ‘ ν μ μλ€
μ½ν
μΈ λ₯Ό λμ μΌλ‘ λ³κ²½νκ³ μΆλ€λ©΄
μΉ λΈλΌμ°μ κ° μΉ μλ²μ μ μν΄
λ³λμ νμΌμμ μ½ν
μΈ λ₯Ό μμ νκ³ μ½μ΄μ€λλ‘ ν μ μλ€
Asynchronous Javascript And Xml (λΉλκΈ°μ μλ°μ€ν¬λ¦½νΈμ xml)
μΉ λΈλΌμ°μ κ° μλ°μ€ν¬λ¦½νΈλ₯Ό μ΄μ©νμ¬ μΉ μλ²μ μ μν΄ μ 보λ₯Ό κ°μ Έμ€λ λ°©λ²
Ajaxλ₯Ό ꡬννκΈ° μν΄ μ¬μ©νλ κΈ°μ
μμ
onclick=" fetch('html').then(function(response){ response.text().then(function(text){ document.querySelector('article').innerHTML = text; }) }) "
μ½κ² νμ΄μ ν΄μνλ©΄,
- μΉ μλ²μ 'html'μ΄λΌλ νμΌμ μμ²νλ€
- μΉ μλ²μ μλ΅μ΄ λλλ©΄ document.que rySelector('article').innerHTML = text; λΆλΆμ΄ μ€νλλ€
- textλΌλ λ³μ μμλ μΉ μλ²κ° μλ΅ν λ°μ΄ν°κ° λ΄κΈ°κ² λλ€
μμ
fetch('html').then(function(response){ console.log(response.status); if (response.status == '404') { alert('not found'); } });
π fetch APIλ₯Ό ν΅ν΄ ν΄λΌμ΄μΈνΈκ° μλ²μκ² μμ²νλλ‘ ν¨
fetch('html')
// μΉ λΈλΌμ°μ μΌ, htmlμ΄λΌλ νμΌμ μλ²μκ² μμ²ν΄μ€.
π μλ²μ μλ΅μ΄ λλ λκΉμ§ λ§λ₯ κΈ°λ€λ¦¬μ§ μκ³ λ€λ₯Έ μ½λκ° ν¨κ» μ€νλ μ μλλ‘ μλ²μ μλ΅μ΄ λλλ©΄ μ€νμν¬ ν¨μλ₯Ό μμ½ν΄λ
function callbackme() {
console.log('response end'); // (μμ μ λ€λ₯΄κ² μμλ‘ μ΄ μ½λ)
}
fetch('html').then(callbackme);
// fetch APIμΌ, μλ²μ μλ΅μ΄ λλλ©΄ λ΄κ° μ μν΄λμ callbackmeλΌλ ν¨μλ₯Ό μ€νμμΌμ€.
console.log(1);
console.log(2);
console μ°½μ μΆλ ₯λλ μμ
1
2
response end
μ¦, fetchκ° μ€νλλ λμμ(μλ²κ° μλ΅νλ λμ) λ€λ₯Έ μ½λκ° ν¨κ» μ€νλ μ μλ€ β λΉλκΈ°μ μΌλ‘ μ€νλλ€
π‘ λΉλκΈ°λ?
μμ²κ³Ό κ²°κ³Όκ° λμμ μΌμ΄λμ§ μλλ€
π fetch APIμ λ€μ΄κ° ν¨μλ λ€λ₯Έ κ³³μμ λΆλ¦΄ μΌμ΄ μκΈ° λλ¬Έμ λ³΄ν΅ μ΅λͺ
ν¨μ
λ₯Ό μ¬μ©νλ€. μμ μμ μ¬μ©ν ν¨μλ μ΅λͺ
ν¨μμ΄λ―λ‘ κ³ μ³μ£Όλ©΄,
fetch('html').then(function(){
console.log('response end');
});
π fetch APIκ° thenμ μ£Όμ΄μ§ μ΅λͺ μ μ½λ°± ν¨μλ₯Ό μ€νμν¬ λ ν¨μμ 첫 λ²μ§Έ μΈμλ‘ responseλΌλ κ°μ²΄λ₯Ό μ€
fetch('html').then(function(response){
console.log(response);
});
π‘
response κ°μ²΄
- fetch APIλ₯Ό ν΅ν΄ 'html'μ μμ²νμ λ μλ²κ° μλ΅ν κ²°κ³Όλ₯Ό λ΄κ³ μλ κ°μ²΄
- κ·Έ μμ± κ°λ€μ ν΅ν΄ μλ²λ ν΅μ μ ν λ μ΄λ€ μνλ‘ ν΅μ μ΄ μ΄λ£¨μ΄μ‘λμ§ μ μ μλ€
π‘ response κ°μ²΄μ
status μμ± κ°
- 200 ok
β μλ²κ° μμ²λ°μ 리μμ€λ₯Ό μ°Ύμλ€ (μμ² μ±κ³΅)
- 304 not modified
β μμ²ν 리μμ€κ° μ΄μ μμ² λμ λΉκ΅ν΄ μμ λμ§ μμλ€
- 404 not found
β μλ²κ° μμ²λ°μ 리μμ€λ₯Ό μ°Ύμ§ λͺ»νλ€ (μμ² μ€ν¨)fetch('javascript').then(function(response){ console.log(response.status); // μλ²κ° μμ²λ°μ 리μμ€λ₯Ό μ°Ύμ§ λͺ»ν κ²½μ°, κ²½κ³ μ°½μ λμ°λλ‘ ν¨ if (response.status == '404') { alert('not found'); } });
μ΄λ¦μ μ§μ ν¨μμ μ¬μ¬μ©ν μ½λ
λ₯Ό λ£μ΄μ€λ€
ν΄λΉ μ½λμμ λ°λ μ μλ λΆλΆ
μ λ³μλ₯Ό λ£μ΄μ€ ν κ°μ λ³μλ₯Ό 맀κ°λ³μμλ μ μ΄ μ€λ€
function fetchPage (name) {
fetch(name).then(function(response){
response.text().then(function(text){
document.querySelector('article').innerHTML = text;
})
});
}
<li><a onclick="fetchPage('html')"></a></li>
<li><a onclick="fetchPage('css')"></a></li>
<li><a onclick="fetchPage('javascript')"></a></li>