노마드코더 / 바닐라 JS로 크롬 앱 만들기 ②

41467 단어 2021.112021.11

1. CSS

js로 스타일을 직접 바꾸는 것은 별로 좋지 않다.
html은 화면 틀을, css는 시각적인 것을, js는 애니매이션적인 것을 담당한다.

// index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css" />
  <title>Momentum</title>
</head>

<body>
  <div class="hello">
    <h1>Click me!</h1>
  </div>
  <script src="app.js"></script>
</body>

</html>

// style.css
body {
  background-color: beige;
}

h1 {
  color: cornflowerblue;
}

.active {
  color: tomato;
}

// app.js
const h1 = document.querySelector("h1")

  if (h1.className === "active") {
    h1.className = "";
  } else {
    h1.className = "active"; // 이런식으로 css를 적용할 수 있다.
  }
}

h1.addEventListener("click", handleTitleClick)

그런데 className을 변경하면 기존에 있던 className을 잃어버린다.

2. classList

// index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css" />
  <title>Momentum</title>
</head>

<body>
  <div class="hello">
    <h1 class="sexy-font">Click me!</h1>
  </div>
  <script src="app.js"></script>
</body>

</html>

// style.css
body {
  background-color: beige;
}

h1 {
  color: cornflowerblue;
}

.clicked {
  color: tomato;
}

.sexy-font {
  font-family: 'Courier New', Courier, monospace;
}

// app.js
const h1 = document.querySelector("h1")

function handleTitleClick() {
  const clickedClass = "clicked"
  if (h1.classList.contains(clickedClass)) {
    h1.classList.remove(clickedClass);
  } else {
    h1.classList.add(clickedClass);
  }
}

h1.addEventListener("click", handleTitleClick)

classList를 활용하면 기존 className인 sexy-font가 사라지지 않고
clicked 가 추가되어 css가 적용되는 것을 확인할 수 있다.

classList.toggle 메소드를 활용하면 if문을 사용하지 않아도 된다.

// app.js
const h1 = document.querySelector("h1")

function handleTitleClick() {
  h1.classList.toggle("clicked")
}

h1.addEventListener("click", handleTitleClick)

참고 : https://developer.mozilla.org/ko/docs/Web/API/Element/classList

3. form

// index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css" />
  <title>Momentum App</title>
</head>

<body>
  <form id="login-form">
    <input 
	required // 필수값 설정 가능
	maxlength="15" // 최대길이도 설정 가능
	type="text" 
	placeholder="What is your name?" />
    <button>Log In</button>
  </form>
  <script src="app.js"></script>
</body>

</html>

// app.js
const loginForm = document.querySelector("#login-form")
const loginInput = document.querySelector("#login-form input")

function onLoginSubmit(event) {
  // addEventListener에서 받는 함수의 첫번째 인자는 우리에게 쓸만한 정보를 줌
  event.preventDefault() // 브라우저의 기본동작을 막는 함수
  console.log(loginInput.value)
}

loginForm.addEventListener("submit", onLoginSubmit)

4. event.preventDefault()

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css" />
  <title>Momentum App</title>
</head>

<body>
  <form id="login-form">
    <input required maxlength="15" type="text" placeholder="What is your name?" />
    <button>Log In</button>
  </form>
  <a href="https://nomadcoders.co">Go to courese</a> // 누르면 페이지 이동
  <script src="app.js"></script>
</body>

</html>

//app.js
function handleLinkClick(event) {
  // event.preventDefault()
  console.log(event) // MouseEvent {}
  alert("click") // 모든 동작을 멈추기 때문에 잘 안쓴다.
}

link.addEventListener("click", handleLinkClick)

alert를 쓰면,
링크를 클릭했을 때, 바로 홈페이지로 넘어가지 않고
알림창이 뜨고 확인을 누른 후에야 홈페이지로 넘어간다.
event.preventDefault() 를 활성화하면
브라우저의 동작을 아예 막는거라서 홈페이지로 이동하지 않는다.
event의 객체를 콘솔창에서 들여다 볼 수 있다.

5. display: none

// index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css" />
  <title>Momentum App</title>
</head>

<body>
  <form id="login-form">
    <input required maxlength="15" type="text" placeholder="What is your name?" />
    <button>Log In</button>
  </form>
  <h1 id="greeting" class="hidden"></h1>
  <script src="app.js"></script>
</body>

</html>

// style.css

.hidden {
  display: none;
}

// app.js

const loginForm = document.querySelector("#login-form")
const loginInput = document.querySelector("#login-form input")
const greeting = document.querySelector("#greeting")

const HIDDEN_CLASSNAME = "hidden"

function onLoginSubmit(event) {
  event.preventDefault() // 새로고침 되는 걸 막고
  loginForm.classList.add(HIDDEN_CLASSNAME) // 안보이게 설정
  const userName = loginInput.value
  greeting.innerHTML = "hello " + userName // text 적용
  greeting.classList.remove(HIDDEN_CLASSNAME) // 보이게 설정
}

loginForm.addEventListener("submit", onLoginSubmit) 
// submit는 브라우저를 새로고침 하게 만듬

6. localStorage

값을 기억하기 위해 localStorage을 사용할 것이다.
개발자도구 콘솔창에 localStorage를 쳐보면 객체가 출력된다.
개발자도구 - application - localStorage를 확인할 수 있다.
key와 value 값이 비어있음을 확인할 수 있다.

콘솔창에 localStorage.setItem("userName", "ej")를 치면
key 에는 userName, value에는 ej 가 들어간다.

localStorage.getItem("userName")를 치면
"ej"가 출력된다.

localStorage.removeItem("userName")를 치면
저장되었던 키와 값이 사라지는 걸 확인할 수 있다.

참고 : https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage

7. mini login

//index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css" />
  <title>Momentum App</title>
</head>

<body>
  <form id="login-form" class="hidden"> // 둘다 안보임
    <input required maxlength="15" type="text" placeholder="What is your name?" />
    <button>Log In</button>
  </form>
  <h1 id="greeting" class="hidden"></h1> // 둘다 안보임
  <script src="app.js"></script>
</body>

</html>

//style.css
.hidden {
  display: none;
}

//app.js
const loginForm = document.querySelector("#login-form")
const loginInput = document.querySelector("#login-form input")
const greeting = document.querySelector("#greeting")

const HIDDEN_CLASSNAME = "hidden"
const USERNAME_KEY = "userName"

function onLoginSubmit(event) {
  event.preventDefault()
  loginForm.classList.add(HIDDEN_CLASSNAME)
  const userName = loginInput.value
  localStorage.setItem(USERNAME_KEY, userName)
  paintGreetings(userName)
}

function paintGreetings(username) {
  greeting.innerHTML = "hello " + username
  greeting.classList.remove(HIDDEN_CLASSNAME)
}

const savedUserName = localStorage.getItem(USERNAME_KEY)

if (savedUserName === null) {
  // show the form 유저정보가 없는 경우
  loginForm.classList.remove(HIDDEN_CLASSNAME) // 로그인 화면을 보여줌
  loginForm.addEventListener("submit", onLoginSubmit) // 유저정보를 받는 이벤트
} else {
  // show the greetings 유저정보가 있는 경우
  paintGreetings(savedUserName) // 환영 화면을 보여줌
}

좋은 웹페이지 즐겨찾기