
HTML과 CSS만으로도 웹페이지는 모냥새를 갖출 수 있다. 하지만 그것만으로는 여전히 정적인 문서일 뿐이다. 버튼을 눌러도, 이미지를 클릭해도 아무 짓도 안 한다.
여기에 JavaScript가 추가되면 상황이 달라진다. 폼 입력을 검증하고, 버튼이 동작하며, 이미지를 바꾸거나 애니메이션을 실행할 수 있다. 즉, 웹페이지가 사용자의 행동에 반응하는 인터랙티브한 공간으로 바뀌는 것이다.
JavaScript는 다른 프로그래밍 언어와 마찬가지로 변수, 조건문, 함수 같은 요소를 갖추고 있다. 웹페이지에서의 동작은 보통 다음 세 단계로 정리할 수 있다.
이 간단한 흐름만 이해하면, 앞으로 만나는 많은 코드들이 같은 패턴으로 돌아감을 알 수 있다.
간단한 할 일 목록이 있다고 하자. CSS에서 .done 클래스를 정의해두고, JavaScript로 리스트 항목을 클릭할 때마다 해당 클래스를 붙였다 떼는 방식으로 구현한다.
.done {
color: darkseagreen;
text-decoration: line-through solid black 2px;
}
const listItems = document.querySelectorAll("li");
function toggleDone(e) {
if (!e.target.className) {
e.target.className = "done";
} else {
e.target.className = "";
}
}
listItems.forEach((item) => {
item.addEventListener("click", toggleDone);
});
리스트 항목을 클릭하면 CSS 스타일이 토글되어 완료 표시가 된다. 불과 몇 줄의 코드지만 페이지가 달라진다.
프로그래밍의 전통적인 첫 예제인 “Hello World”도 빠질 수 없다.
HTML에 스크립트를 연결한다.
<script async src="scripts/main.js"></script>
main.js 파일에 다음을 작성한다.
const myHeading = document.querySelector("h1");
myHeading.textContent = "Hello world!";
<h1> 요소를 선택한 뒤 텍스트 내용을 교체하는 단순한 코드다. DOM 조작의 기본을 보여준다.
이미지를 클릭할 때 다른 이미지로 바꿔보자.
const myImage = document.querySelector("img");
myImage.addEventListener("click", () => {
const mySrc = myImage.getAttribute("src");
if (mySrc === "images/firefox-icon.png") {
myImage.setAttribute("src", "images/firefox2.png");
} else {
myImage.setAttribute("src", "images/firefox-icon.png");
}
});
조건문으로 이미지의 src 값을 확인하고, 클릭할 때마다 교체한다. 결과적으로 사용자가 클릭할 때마다 두 이미지가 번갈아 나타난다.
이 과정에서 몇 가지 핵심 용어가 등장한다.
if...else 구조가 기본이다.이번에는 사용자가 입력한 이름을 저장해두고 다시 보여주는 기능을 구현한다. 여기서는 Web Storage API를 사용한다.
HTML에 버튼을 하나 추가한다.
<button>Change user</button>
main.js에는 다음을 작성한다.
let myButton = document.querySelector("button");
let myHeading = document.querySelector("h1");
function setUserName() {
const myName = prompt("Please enter your name.");
localStorage.setItem("name", myName);
myHeading.textContent = `Mozilla is cool, ${myName}`;
}
if (!localStorage.getItem("name")) {
setUserName();
} else {
const storedName = localStorage.getItem("name");
myHeading.textContent = `Mozilla is cool, ${storedName}`;
}
myButton.addEventListener("click", () => {
setUserName();
});
처음 페이지에 들어오면 이름을 묻고, 입력값을 localStorage에 저장한다. 이후 새로고침을 해도 저장된 이름이 그대로 표시된다. 버튼을 누르면 다시 이름을 바꿀 수도 있다.
문제는 사용자가 이름 입력을 취소하거나 빈 값을 넣었을 때다.
null이 저장되어 Mozilla is cool, null이 된다.Mozilla is cool, 처럼 어색한 결과가 된다.이를 막으려면 조건문을 추가한다.
function setUserName() {
const myName = prompt("Please enter your name.");
if (!myName) {
setUserName();
} else {
localStorage.setItem("name", myName);
myHeading.textContent = `Mozilla is cool, ${myName}`;
}
}
값이 없을 경우 다시 입력을 요청하는 방식이다.