1. Login 창 구현
<div id="login-form">
<input
required
maxlength="15"
type="text"
placeholder="What is your name?"
/>
<button>Log In</button>
</div>
<script src="app.js"></script>
const loginForm = document.querySelector("#login-form");
const loginInput = loginForm.querySelector("input");
const loginButton = loginForm.querySelector("button");
// 위의 다른 방법
// const loginInput = document.querySelector("#login-form input");
// const loginButton = document.querySelector("#login-form button");
function handleLoginBtnClick() {
console.dir(loginInput);
console.log("click!!");
}
loginButton.addEventListener("click", handleLoginBtnClick);
- value : 기본적으로 input 안에 있는 텍스트(현재 작성 중인 로그인 창 코드를 기준으로)
input의 내용을 가져오려면 value에 접근해야 함
input에 입력받는 value의 조건을 설정(if 조건문)
const loginForm = document.querySelector("#login-form");
const loginInput = loginForm.querySelector("input");
const loginButton = loginForm.querySelector("button");
// 위의 다른 방법
// const loginInput = document.querySelector("#login-form input");
// const loginButton = document.querySelector("#login-form button");
function handleLoginBtnClick() {
const username = loginInput.value;
if (username === "") {
alert("Please write your name.");
} else if (username.length > 15) {
alert("Your name is too long!");
} else {
}
}
loginButton.addEventListener("click", handleLoginBtnClick);
- input은 더욱 많은 것을 할 수 있음
1. required를 이용하여 input을 필수입력 항목으로 만들어 줄 수 있으며,
2. maxlength="15"를 이용하여 자체작으로 최대 글자수를 15로 조절할 수도 있음
3. input의 유효성 검사를 작동시키기 위해서는 input이 form 안에 있어야만 함
(html의 도움을 활용하려면 input을 form 안에 위치시켜야 함)
submit라는 이벤트 함수는 form에서만 작동함
button의 type은 submit로 맞춰주고 그 버튼을 클릭시 form에 onSubmit를 통해 이벤트 작동
이렇게 input을 설정해준 후 handleLoginBtnClick function을 이렇게 설정해줌(조건문 지우고)
<form id="login-form">
<input
required
maxlength="15"
type="text"
placeholder="What is your name?"
/>
<button type="submit" value="Log In">Log In</button>
</form>
<script src="app.js"></script>
function handleLoginBtnClick() {
const username = loginInput.value;
console.log(username);
}
input에 설정을 해놨기 때문에 text 수는 15글자를 넘어가지 못함
- 값을 입력하고 버튼을 누르면 새로고침이 실행됨. 값이 사라짐
form이 submit 되어서 웹사이트를 재시작시키고 있는 것.
우리가 form 안에서 엔터를 누르고 input이 더 존재하지 않는다면 자동으로 submit 된다는 규칙
- 우리는 브라우저가 새로고침하지 않고 user 정보를 저장하도록 하고 싶은 것!
우리는 이제 button의 클릭 여부 말고 form의 submit에 관심이 있음
1. form을 submit 할 때 입력값을 받아내자
<form id="login-form">
<input
required
maxlength="15"
type="text"
placeholder="What is your name?"
/>
<button type="submit" value="Log In">Log In</button>
</form>
<script src="app.js"></script>
const loginForm = document.querySelector("#login-form");
const loginInput = loginForm.querySelector("input");
// 위의 다른 방법
// const loginInput = document.querySelector("#login-form input");
// const loginButton = document.querySelector("#login-form button");
function onLoginSubmit() {
const username = loginInput.value;
console.log(username);
}
loginForm.addEventListener("submit", onLoginSubmit);
const loginForm = document.querySelector("#login-form");
const loginInput = loginForm.querySelector("input");
// 위의 다른 방법
// const loginInput = document.querySelector("#login-form input");
// const loginButton = document.querySelector("#login-form button");
function onLoginSubmit(event) {
event.preventDefault(); // 새로고침이 일어나 정보가 사라지지 않도록
console.log(event);
}
loginForm.addEventListener("submit", onLoginSubmit);
- 가끔씩 우리는 함수를 통하여 기본 동작이 아닌, 뭐가 클릭됐는지 어디가 클릭됐는지 등 정보를 알고 싶을 때가 있음
const loginForm = document.querySelector("#login-form");
const loginInput = loginForm.querySelector("input");
const link = document.querySelector("a");
// 위의 다른 방법
// const loginInput = document.querySelector("#login-form input");
// const loginButton = document.querySelector("#login-form button");
function onLoginSubmit(event) {
event.preventDefault(); // 새로고침이 일어나 정보가 사라지지 않도록
console.log(event);
}
function handleLinkClick(event) {
console.log(event); // event에 관한 여러 정보들 확인
alert("click!");
}
loginForm.addEventListener("submit", onLoginSubmit);
link.addEventListener("click", handleLinkClick);
함수를 실행시키는 동시에 그 함수에 첫 번째 인자로 object를 넣어줌
andletLinkClick( { information about the event that just happened } );
이 object에는 방금 일어난 event에 대한 여러 정보가 담겨 있음
- a 링크를 타고 이동하는 것을 방지
브라우저는 링크를 클릭할 때 해당 사이트로 이동하도록 설정되어 있는데
자바스크립트가 그것을 막고 있는 것
function handleLinkClick(event) {
event.preventDefault(); // a 링크를 클릭했을 때 사이트로 이동되는 것을 방지(기본 동작을 막음)
console.log(event); // event에 관한 여러 정보들 확인
alert("click!");
}
- 유저가 이름을 클릭하면 form을 없애고 싶음
1. css를 통하여 숨기는 것
css에 hidden이라는 class name을 만들어줌
.hidden {
display: none;
}
2. 클릭시 html 요소 자체를 없애고, 입력받은 value값이 h1태그에 나타나는 것
const loginForm = document.querySelector("#login-form");
const loginInput = loginForm.querySelector("input");
const greeting = document.querySelector("#greeting");
const HIDDEN_CLASSNAME = "hidden";
// 일반적으로 string만 포함된 변수는 대문자로 표기하고 string을 저장하고 싶을 때 사용
// 이건 loginForm이나 loginInput처럼 중요한 정보를 담은게 아니라서 대문자로 작성
// 위의 다른 방법
// const loginInput = document.querySelector("#login-form input");
// const loginButton = document.querySelector("#login-form button");
function onLoginSubmit(event) {
event.preventDefault(); // 새로고침이 일어나 정보가 사라지지 않도록
loginForm.classList.add(HIDDEN_CLASSNAME);
const username = loginInput.value;
// greeting.innerText = "Hello " + username;
// 이런 방식은 좋지 않음. 간격도 기억해야 하고 +도 보기 좋지 않음
greeting.innerText = `Hello ${username}`;
// 이 방식은 두 가지 규칙이 있음.
// 규칙 하나는 내가 만약 변수와 string을 결합하고 싶다면, 또는 변수를 string 안에 집어넣고 싶다면
// ${변수명} 이렇게 표현하면 끝
// 규칙 둘은 `` 이 기호로 시작해야 한다는 것 : 백틱
greeting.classList.remove(HIDDEN_CLASSNAME);
}
// function handleLinkClick(event) {
// event.preventDefault(); // a 링크를 클릭했을 때 사이트로 이동되는 것을 방지(기본 동작을 막음)
// console.dir(event); // event에 관한 여러 정보들 확인
// }
loginForm.addEventListener("submit", onLoginSubmit);
- username 저장하기
value를 저장하는 방법을 배우는 것. user에게 매번 질문하기에는 번거롭기 때문
무언가를 저장하는 것은 유저의 이름이 아니라고 할 지라도 정말 자주 사용되는 기능.
ex) 유튜브에서 우리가 볼륨을 조절하고 새로고침을 하면 유튜브가 그 볼륨값을 기억
우리가 브라우저에 공짜로 뭔가를 기억할 수 있게 해주는 API가 존재.
API의 이름은 local storage => 우리가 브라우저에 뭔가를 저장할 수 있게 해줌(나중에 다시 가져다 쓸 수 있음)
1. local storage API에는 setItem이라는 method가 있음 => 이것을 활용하면 local storage에 정보를 저장할 수 있음
localStorage.setItem("username", username);
// 첫 번째는 저장될 item의 이름이고, 값은 username 변수
2. getItem이라는 method를 이용하여 저장된 정보를 가져올 수도 있음
localStorage.getItem("username")
<form id="login-form" class="hidden">
<input
required
maxlength="15"
type="text"
placeholder="What is your name?"
/>
<button type="submit" value="Log In">Log In</button>
</form>
<h1 id="greeting" class="hidden"></h1>
<script src="app.js"></script>
.hidden {
display: none;
}
const loginForm = document.querySelector("#login-form");
const loginInput = loginForm.querySelector("input");
const greeting = document.querySelector("#greeting");
const HIDDEN_CLASSNAME = "hidden";
const USERNAME_KEY = "username";
// 일반적으로 string만 포함된 변수는 대문자로 표기하고 string을 저장하고 싶을 때 사용
// 이건 loginForm이나 loginInput처럼 중요한 정보를 담은게 아니라서 대문자로 작성
// 위의 다른 방법
// const loginInput = document.querySelector("#login-form input");
// const loginButton = document.querySelector("#login-form button");
function onLoginSubmit(event) {
event.preventDefault(); // 새로고침이 일어나 정보가 사라지지 않도록
loginForm.classList.add(HIDDEN_CLASSNAME);
const username = loginInput.value;
localStorage.setItem(USERNAME_KEY, username);
// greeting.innerText = "Hello " + username;
// 이런 방식은 좋지 않음. 간격도 기억해야 하고 +도 보기 좋지 않음
greeting.innerText = `Hello ${username}`;
// 이 방식은 두 가지 규칙이 있음.
// 규칙 하나는 내가 만약 변수와 string을 결합하고 싶다면, 또는 변수를 string 안에 집어넣고 싶다면
// ${변수명} 이렇게 표현하면 끝
// 규칙 둘은 `` 이 기호로 시작해야 한다는 것 : 백틱
greeting.classList.remove(HIDDEN_CLASSNAME);
}
// function handleLinkClick(event) {
// event.preventDefault(); // a 링크를 클릭했을 때 사이트로 이동되는 것을 방지(기본 동작을 막음)
// console.dir(event); // event에 관한 여러 정보들 확인
// }
loginForm.addEventListener("submit", onLoginSubmit);
const savedUsername = localStorage.getItem(USERNAME_KEY);
if (savedUsername === null) {
// local storage에 유저 정보가 없을 때
// show the form
loginForm.classList.remove(HIDDEN_CLASSNAME);
loginForm.addEventListener("submit", onLoginSubmit);
} else {
// show the greeting
greeting.classList.remove(HIDDEN_CLASSNAME);
greeting.innerText = `Hello ${savedUsername}`;
}
uername이 없으면 null 값을 결과로 받고 있음
3. 필요한 경우 removeItem method를 이용하여 저장된 값을 지울 수도 있음
localstorage.removeItam("username");
마치 작은 미니 DB 같은 것. 우리는 key와 value만 준비하면 됨
- 하지만 여전히 새로고침을 하면 input이 표시되고 있음
우리는 우선 local storage에 username이 존재하는지 확인하고,
존재하는 경우 바로 h1 요소가 표시되도록 할 것임
만약 local storage에 유저정보가 없다면 form이 먼저 표시되도록 할 것임
- 우리는 같은 행동을 두 번 반복하고 있음
greeting.innerText랑 greeting.classList.remove를 반복
const loginForm = document.querySelector("#login-form");
const loginInput = loginForm.querySelector("input");
const greeting = document.querySelector("#greeting");
const HIDDEN_CLASSNAME = "hidden";
const USERNAME_KEY = "username";
// 일반적으로 string만 포함된 변수는 대문자로 표기하고 string을 저장하고 싶을 때 사용
// 이건 loginForm이나 loginInput처럼 중요한 정보를 담은게 아니라서 대문자로 작성
function onLoginSubmit(event) {
event.preventDefault(); // 새로고침이 일어나 정보가 사라지지 않도록
loginForm.classList.add(HIDDEN_CLASSNAME);
const username = loginInput.value;
localStorage.setItem(USERNAME_KEY, username);
// greeting.innerText = `Hello ${username}`;
// greeting.classList.remove(HIDDEN_CLASSNAME);
paintGreetings(username);
}
// function handleLinkClick(event) {
// event.preventDefault(); // a 링크를 클릭했을 때 사이트로 이동되는 것을 방지(기본 동작을 막음)
// console.dir(event); // event에 관한 여러 정보들 확인
// }
loginForm.addEventListener("submit", onLoginSubmit);
// greeting.innerText랑 greeting.classList.remove를 반복하고 있음
// 이걸 함수로 나타내기
function paintGreetings(username) {
greeting.innerText = `Hello ${username}`;
greeting.classList.remove(HIDDEN_CLASSNAME);
}
const savedUsername = localStorage.getItem(USERNAME_KEY);
if (savedUsername === null) {
// local storage에 유저 정보가 없을 때
// show the form
loginForm.classList.remove(HIDDEN_CLASSNAME);
loginForm.addEventListener("submit", onLoginSubmit);
} else {
// show the greeting
paintGreetings(savedUsername);
}
- 생각해보면 paintGreetings 함수는 따로 인자를 받을 필요가 없음
왜냐, 우리는 local storage에 유저정보가 존재하는 걸 알고 있기 때문
// 인자는 빼주고 변수 username 추가
function paintGreetings() {
const username = localStorage.getItem(USERNAME_KEY);
greeting.innerText = `Hello ${username}`;
greeting.classList.remove(HIDDEN_CLASSNAME);
}
local storage에 뭔가를 저장하면 paintGreetings를 호출하는 순간에
그 유저정보는 이미 local storage에 저장되어 있을 거임
어쩌면 유저 정보를 두 번씩이나 찾고 싶지 않을 수도 있음
onLoginSubmit function 안에 username 변수를 없애주고
localStorage.setItem(USERNAME_KEY, username); →
localStorage.setItem(USERNAME_KEY, loginInput.value); 변경
function onLoginSubmit(event) {
event.preventDefault(); // 새로고침이 일어나 정보가 사라지지 않도록
loginForm.classList.add(HIDDEN_CLASSNAME);
localStorage.setItem(USERNAME_KEY, loginInput.value);
// greeting.innerText = "Hello " + username;
// 이런 방식은 좋지 않음. 간격도 기억해야 하고 +도 보기 좋지 않음
// * greeting.innerText = `Hello ${username}`;
// 이 방식은 두 가지 규칙이 있음.
// 규칙 하나는 내가 만약 변수와 string을 결합하고 싶다면, 또는 변수를 string 안에 집어넣고 싶다면
// ${변수명} 이렇게 표현하면 끝
// 규칙 둘은 `` 이 기호로 시작해야 한다는 것 : 백틱
// * greeting.classList.remove(HIDDEN_CLASSNAME);
paintGreetings();
}
보다시피 똑같이 작동하고 있지만 다른 점은 local storage를 두 번 열어본다는 것
function paintGreetings() {
const username = localStorage.getItem(USERNAME_KEY);
greeting.innerText = `Hello ${username}`;
greeting.classList.remove(HIDDEN_CLASSNAME);
}
const savedUsername = localStorage.getItem(USERNAME_KEY);
local storage를 두 번 열어볼 필요가 없다고 생각한다면 이전 방법을 사용해도 됨
2. 시계 만들기
<form id="login-form" class="hidden">
<input
required
maxlength="15"
type="text"
placeholder="What is your name?"
/>
<button type="submit" value="Log In">Log In</button>
</form>
<h2 id="clock">00:00:00</h2>
<h1 id="greeting" class="hidden"></h1>
<script src="js/greetings.js"></script>
<script src="js/clock.js"></script>
const clock = document.querySelector("h2#clock");
// 우리는 1초, 2초, 3초일 때도 두 자릿수로 나타내고 싶음
// padStart()라는 function으로 이미 만들어져 있음 => string에 쓸 수 있는 function
// "1".padStart(2,0); => string의 길이를 2로 만드는데 만약 그 string의 길이가 2가 아니라면 앞쪽에 0을 추가하도록)
function getClock() {
const date = new Date();
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
// clock.innerText = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
clock.innerText = `${hours}:${minutes}:${seconds}`;
}
// 함수를 정해진 시간마다 호출하는 것
// setInterval은 두 개의 argument를 받음
// 첫 번째는 내가 실행하고자 하는 function, 두 번재는 호출되는 function의 간격(ms) - 간격을 띄어가면서 호출
setInterval(getClock, 1000); // 매 초마다 시간을 가져오도록
// 함수를 정해진 시간만큼 기다린 후에 한 번만 호출
// 첫 번째는 호출하려고 하는 function을 넣어주고, 두 번째는 얼마나 기다릴지 ms 단위로 - 한 번만 호출
//setTimeout(getClock, 5000);
// 시계를 만들기 위해서 javascript가 가지고 있는 "Date object"를 사용해보자
// new Date(); => 이런식으로 사용할 수 있음
// getDate, getDay, getFullYear, getHours, getMilliseconds 등 쓸 수 있는 method가 많음
// date.getDate() => 29
// date.getDay() => 2(화요일이기 때문 => 일요일이 0)
// date.getFullYear() => 2022
// date.getHours() => 16(오후 4시)
// date.getMinutes() => 53(분)
// date.getSeconds() => 우리는 date.getFullYear(), date.getHours(), date.getMinutes() 세 개를 매 초마다 호출해줘야 함
3. 랜덤 배경과 랜덤 명언 만들기
3-1. 랜덤 명언 만들기
<form id="login-form" class="hidden">
<input
required
maxlength="15"
type="text"
placeholder="What is your name?"
/>
<button type="submit" value="Log In">Log In</button>
</form>
<h2 id="clock">00:00:00</h2>
<h1 id="greeting" class="hidden"></h1>
<div id="quote">
<span></span>
<span></span>
</div>
<script src="js/greetings.js"></script>
<script src="js/clock.js"></script>
<script src="js/quotes.js"></script>
const quotes = [
{
quote: "I respect faith, but doubt is what gets you an education.",
author: "Bruce Lee",
},
{
quote:
"What we once did 'for the sake of God' we now do for the sake of money.",
author: "Friedrich Nietzsche",
},
{
quote: "Education has for its object the formation of character.",
author: "Herbert Spencer",
},
{
quote:
"To repeat what others have said, requires education; to challenge it, requires brains.",
author: "Mary Pettibone Poole",
},
{
quote: "A man has to have a code, a way of life to live by.",
author: "John Wayne",
},
{
quote: "Maturity is only a short break in adolescence.",
author: "Jules Feiffer",
},
{
quote: "There is more to life than increasing its speed",
author: "Mahatma Gandhi",
},
{
quote:
"We improve ourselves by victories over ourself. There must be contests, and you must win.",
author: "Edward Gibbon",
},
{
quote: "Happiness gives us the energy which is the basis of health.",
author: "Henri-Frederic Amiel",
},
{
quote: "A minute's success pays the failure of years.",
author: "Robert Browning",
},
];
const quote = document.querySelector("div#quote span:first-child");
const author = document.querySelector("div#quote span:last-child");
// 첫 번째, Array 안에 있는 element에 어떻게 접근할 것인가?
// 우리는 0부터 9까지의 숫자를 주는 function이 필요 => javascript의 Math module 사용
// Math에는 흥미로운 function이 많이 있음. 그 중 하나는 random(); => 0부터 1 사이의 랜덤한 숫자를 제공
// Math.random() * 10 => 0부터 10 사이의 숫자들을 얻을 수 있음(하지만 정수가 아니기 때문에 소숫점들이 붙어 있음)
// 소숫점을 없애기 위하여 세 가지 방법을 사용할 수 있음
// 1. round() => 숫자를 반올림시킴 => 1.4는 1로, 1.8은 2로
// 2. ceil() => 숫자를 천장(ceil)까지 높여주는 것 => 1.1은 2
// 3. floor() => 숫자를 바닥(floor)까지 낮춰주는 것 => 1.8은 1
const todaysQuote = quotes[Math.floor(Math.random() * quotes.length)];
// 이렇게 하면 랜덤으로 명언을 가져옴(todaysQuote 변수에 저장)
// 우리는 여기 숫자 10을 hard coding했음
// 이것은 우리가 딱 10개의 명언들을 가지고 있을 때만 동작
// 명언 하나를 추가하려면 Array의 길이를 알아내는 것이 좋음
// 이제 명언과 작가를 화면에 보이게끔 하자
// todayQuote가 quote랑 author을 가지고 있음
quote.innerText = todaysQuote.quote;
author.innerText = todaysQuote.author;
3-2. 랜덤 배경 만들기
먼저, images라는 폴더 안에 이미지들 넣어주기
<form id="login-form" class="hidden">
<input
required
maxlength="15"
type="text"
placeholder="What is your name?"
/>
<button type="submit" value="Log In">Log In</button>
</form>
<h2 id="clock">00:00:00</h2>
<h1 id="greeting" class="hidden"></h1>
<div id="quote">
<span></span>
<span></span>
</div>
<script src="js/greetings.js"></script>
<script src="js/clock.js"></script>
<script src="js/quotes.js"></script>
<script src="js/background.js"></script>
// 폴더 안에 있는 이미지 이름들은 javascript 파일에서도 동일하게 사용
const images = [
"1.png",
"2.png",
"3.png",
"4.png",
"5.png",
"6.png",
"7.png",
"8.png",
"9.png",
"10.png",
];
const todaysImg = images[Math.floor(Math.random() * images.length)];
// javascript에서 뭔가를 생성해서 그걸 html에 추가해 볼 것임
// 우리의 목표는 html에 <img src="img/1.png"/> 이런식으로 추가하는 것
// javascript에서 이미지를 만들고 이걸 html에 추가해야 함
// createElement를 이용하여 js에 HTML 요소를 만들 수 있음
const bgImage = document.createElement("img");
bgImage.src = `images/${todaysImg}`;
// bgImage를 body 내부에 추가해주기
// appendChild()를 이용하여 body에 html을 추가하기(부모객체 요소 아래 삽입)
// append() => 선택된 요소의 마지막에 새로운 요소나 콘텐츠 추가
// perpend() => 선택된 요소의 첫 번째에 새로운 요소나 콘텐츠를 추가
document.body.appendChild(bgImage);
4. TO DO LIST 만들기
<form id="login-form" class="hidden">
<input
required
maxlength="15"
type="text"
placeholder="What is your name?"
/>
<button type="submit" value="Log In">Log In</button>
</form>
<h2 id="clock">00:00:00</h2>
<h1 id="greeting" class="hidden"></h1>
<form id="todo-form">
<input
type="text"
placeholder="Write a To Do and Press Enter."
required
/>
</form>
<ul id="todo-list">
<!-- javascript로 li를 추가할 것이기 때문에 비워둠 -->
</ul>
<div id="quote">
<span></span>
<span></span>
</div>
<script src="js/greetings.js"></script>
<script src="js/clock.js"></script>
<script src="js/quotes.js"></script>
<script src="js/background.js"></script>
<script src="js/todo.js"></script>
'(심층)자바스크립트' 카테고리의 다른 글
타강의 2-2) 자바스크립트 (1) | 2022.12.01 |
---|---|
타강의 2-1) 자바스크립트 (0) | 2022.12.01 |
타강의 2) 자바스크립트 (0) | 2022.11.26 |
짧게 짧게 알게 된 것 정리 1 (0) | 2022.11.25 |
타강의 1) 자바스크립트 (0) | 2022.11.17 |
github : https://github.com/dnjfht
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!