이전 단계에서는 JavaScript 파일을 연결하고, 메모 추가 버튼을 눌렀을 때 입력값이 콘솔에 출력되는지 확인했다.
이번 단계에서는 콘솔 출력에서 끝내지 않고, 사용자가 입력한 제목과 내용을 실제 화면의 메모 목록에 추가하도록 구현했다.
아직 localStorage 저장은 하지 않았다.
따라서 새로고침하면 추가한 메모는 사라진다.
이번 단계의 목표는 브라우저 화면 안에서 메모를 동적으로 추가하는 흐름을 이해하는 것이다.
처음 작성했던 코드의 문제
처음에는 입력값을 변수에 미리 담아두고, 그 값을 이용해서 메모를 추가하려고 했다.
const titleInput = document.getElementById("memo-title");
const contentInput = document.getElementById("memo-content");
const addMemoButton = document.getElementById("add-memo-button");
const memoContainer = document.getElementById("memo-container");
const emptyMessage = document.getElementById("empty-message");
const title = titleInput.value;
const content = contentInput.value;
그런데 이렇게 작성하면 문제가 생긴다.
`titleInput.value`와 `contentInput.value`는 페이지가 처음 로드될 때 실행된다.
페이지가 처음 열렸을 때는 사용자가 아직 아무것도 입력하지 않은 상태이므로, title과 content에는 빈 문자열이 들어간다.
즉, 입력값은 페이지가 열릴 때 가져오는 것이 아니라 버튼을 클릭한 순간 가져와야 한다.
정리하면 흐름은 이렇게 되어야 한다.
페이지 열림
→ 사용자가 제목과 내용 입력
→ 메모 추가 버튼 클릭
→ 그 순간 input과 textarea의 현재 값 읽기
→ 메모 카드 생성
→ 화면에 추가
return 위치 오류
처음에는 빈 값 검사를 이벤트 함수 밖에 작성했다.
if (title === '' || content === '') {
alert('제목과 내용을 모두 입력하세요.');
return;
}
이렇게 작성하니 다음 오류가 발생했다.
'return' outside function definition
return은 함수 안에서만 사용할 수 있다.
따라서 빈 값 검사도 버튼 클릭 이벤트 함수 안으로 넣어야 했다.
addMemoButton.addEventListener('click', function () {
if (title === '' || content === '') {
alert('제목과 내용을 모두 입력하세요.');
return;
}
});
여기서 return은 제목이나 내용이 비어 있을 때, 그 아래 메모 추가 코드를 실행하지 않고 함수를 끝내는 역할을 한다.
메모 생성 코드 위치
메모를 만드는 코드도 처음에는 클릭 이벤트 밖에 작성하려고 했다.
하지만 메모는 페이지가 열릴 때 만들어지는 것이 아니라, 사용자가 버튼을 클릭했을 때 만들어져야 한다.
그래서 다음 작업들은 모두 클릭 이벤트 함수 안에 있어야 한다.
- 입력값 가져오기
- 빈 값 검사하기
- 새 div 만들기
- 메모 카드 내용 넣기
- 화면에 추가하기
- 입력창 비우기
이 부분을 정리하면서, 이벤트 기반 코드의 흐름을 조금 더 이해할 수 있었다.
문자열 안에 변수 넣기
메모 카드의 HTML을 만들 때도 한 가지 문제가 있었다.
처음에는 이렇게 작성했다.
memoCard.innerHTML = '' +
'<h3>${title}</h3>' +
'<p>${content}</p>' +
'<button type="button">삭제</button>';
하지만 작은따옴표 안에서는 ${title}과 ${content}가 변수로 해석되지 않는다.
그냥 글자 그대로 출력된다.
변수 값을 문자열 안에 넣으려면 백틱을 사용해야 한다.
memoCard.innerHTML = `
<h3>${title}</h3>
<p>${content}</p>
<button type="button">삭제</button>
`;
이 방식을 템플릿 리터럴이라고 한다.
문자열 안에 변수 값을 넣을 때 훨씬 편하게 사용할 수 있다.
최종 코드
이번 단계에서 정리한 script.js 코드는 다음과 같다.
const titleInput = document.getElementById("memo-title");
const contentInput = document.getElementById("memo-content");
const addMemoButton = document.getElementById("add-memo-button");
const memoContainer = document.getElementById("memo-container");
const emptyMessage = document.getElementById("empty-message");
addMemoButton.addEventListener('click', function () {
const title = titleInput.value;
const content = contentInput.value;
console.log('메모 추가 버튼 클릭');
console.log(title);
console.log(content);
if (title === '' || content === '') {
alert('제목과 내용을 모두 입력하세요.');
return;
}
const memoCard = document.createElement('div');
memoCard.className = 'memo-card';
memoCard.innerHTML = `
<h3>${title}</h3>
<p>${content}</p>
<button type="button">삭제</button>
`;
memoContainer.appendChild(memoCard);
emptyMessage.style.display = 'none';
titleInput.value = '';
contentInput.value = '';
});
전체 흐름은 다음과 같다.
1. HTML 요소들을 JavaScript로 가져온다.
2. 메모 추가 버튼에 click 이벤트를 등록한다.
3. 사용자가 버튼을 클릭한다.
4. 클릭한 순간 제목과 내용 값을 가져온다.
5. 제목이나 내용이 비어 있으면 alert를 띄우고 함수를 종료한다.
6. 값이 있으면 새 div 요소를 만든다.
7. 새 div에 memo-card 클래스를 붙인다.
8. innerHTML로 메모 카드 내부 구조를 만든다.
9. memoContainer 안에 새 메모 카드를 추가한다.
10. 메모가 생겼으므로 emptyMessage를 숨긴다.
11. 입력창을 빈 값으로 초기화한다.
새 요소 만들기
이번 단계에서 처음으로 JavaScript를 이용해 HTML 요소를 직접 만들었다.
const memoCard = document.createElement('div');
이 코드는 새로운 div 요소를 만든다.
처음부터 HTML 파일에 적혀 있던 요소가 아니라, JavaScript가 실행 중에 새로 만드는 요소다.
사용자가 메모를 추가할 때마다 새로운 메모 카드가 만들어진다.
클래스 붙이기
새로 만든 div에는 memo-card 클래스를 붙였다.
memoCard.className = 'memo-card';
결과적으로 다음과 같은 요소가 만들어진다.
<div class="memo-card"></div>
이렇게 클래스를 붙이면 나중에 CSS에서 .memo-card를 선택해서 메모 카드 스타일을 줄 수 있다.
메모 카드 내용 넣기
메모 카드 내부에는 innerHTML을 사용해서 제목, 내용, 삭제 버튼을 넣었다.
memoCard.innerHTML = `
<h3>${title}</h3>
<p>${content}</p>
<button type="button">삭제</button>
`;
결과적으로 화면에는 다음과 같은 구조가 추가된다.
<div class="memo-card">
<h3>사용자가 입력한 제목</h3>
<p>사용자가 입력한 내용</p>
<button type="button">삭제</button>
</div>
화면에 추가하기
새로 만든 메모 카드는 memoContainer 안에 추가했다.
memoContainer.appendChild(memoCard);
기존 HTML에는 비어 있는 메모 목록 영역이 있었다.
<div id="memo-container"></div>
메모를 추가하면 이 영역 안에 새 메모 카드가 들어간다.
<div id="memo-container">
<div class="memo-card">
<h3>제목</h3>
<p>내용</p>
<button type="button">삭제</button>
</div>
</div>
빈 메시지 숨기기
처음 화면에는 메모가 없기 때문에 안내 문구가 보인다.
<p id="empty-message" class="empty-message">아직 작성된 메모가 없습니다.</p>
하지만 메모가 하나라도 추가되면 이 문구는 필요하지 않다.
emptyMessage.style.display = 'none';
이 코드는 emptyMessage 요소의 display 값을 none으로 바꿔서 화면에서 숨긴다.
입력창 비우기
메모를 추가한 뒤에는 입력창을 다시 비워주었다.
titleInput.value = '';
contentInput.value = '';
이렇게 하면 메모를 추가한 뒤 바로 다음 메모를 입력할 수 있는 상태가 된다.
'Project > Memo Evolution' 카테고리의 다른 글
| #6 메모 내용 줄바꿈 처리하기 (0) | 2026.06.11 |
|---|---|
| #5 메모데이터를 배열로 관리 (0) | 2026.06.11 |
| #3 JavaScript 연결하고 버튼 클릭 감지 (0) | 2026.06.10 |
| #2 CSS로 메모장 화면 꾸미기 (0) | 2026.06.10 |
| #1 HTML로 메모장 화면 뼈대 만들기 (0) | 2026.06.09 |