할 일 입력 칸에 글자를 치고 Enter를 누르거나 옆의 '추가' 단추를 누르면, 브라우저는 바깥 <form> 요소에 submit(제출) 이벤트를 일으킵니다. 이때 브라우저의 기본 새로고침을 **event.preventDefault()**로 막고, **input.value**에서 입력 글자를 꺼내 다듬는 법을 알아봅니다.
1폼 제출과 event.preventDefault()
할 일 앱의 폼(#todo-form) 안에는 입력 칸(#todo-input)과 제출 단추(<button type="submit">)가 들어 있습니다.
<form id="todo-form">
<input
id="todo-input"
type="text"
/>
<button type="submit">
추가
</button>
</form>단추에 'click' 리스너를 따로 붙이는 대신 form에 'submit' 리스너 하나만 붙이면, 단추를 마우스로 누를 때와 입력 칸에서 Enter 키를 칠 때를 한꺼번에 처리할 수 있습니다.
'use strict';
const form = document
.querySelector('#todo-form');
const input = document
.querySelector('#todo-input');
이어서 form에 'submit' 리스너를 등록합니다.
form.addEventListener(
'submit',
(event) => {
event.preventDefault();
const text =
input.value.trim();
if (text === '') return;
console.log('추가:', text);
input.value = '';
},
);
' 장보기 '를 치고 Enter:
Console 탭: 추가: 장보기
(새로고침 없이 입력 칸 비워짐)event.preventDefault(): 브라우저에서<form>의 기본 동작은 서버로 데이터를 보내며 페이지를 새로고침하는 것입니다. 첫 줄에서event.preventDefault()를 불러야 새로고침되어 변수들이 초기화되는 일을 막을 수 있습니다.input.value.trim(): 사용자가 입력 칸에 친 글자는input.textContent가 아니라 **input.value**에 들어 있습니다..trim()으로 앞뒤 공백을 깎아 내고, 공백만 쳐서text === ''이면return으로 빠져나옵니다.input.value = '': 할 일을 추가한 뒤에는 입력 칸에 빈 문자열을 대입해 칸을 깨끗이 비웁니다.
2input.value는 언제나 문자열이다
<input type="number">처럼 숫자 입력 칸을 쓰더라도, 자바스크립트에서 읽은 **input.value의 타입은 언제나 string(문자열)**입니다.
두 입력 칸에 2와 3을 치고 Number()로 바꾸지 않은 채 +로 더하면 어떻게 되는지 Node로 확인해 봅니다.
const inA = { value: '2' };
const inB = { value: '3' };
console.log(typeof inA.value);
console.log(
inA.value + inB.value,
);
console.log(
Number(inA.value) +
Number(inB.value),
);
string
23
5'2' + '3'은 문자열 이어 붙이기가 되어 '23'이 나옵니다. 수량이나 금액처럼 숫자 계산을 해야 할 때는 반드시 **Number(input.value)**로 숫자로 바꾼 뒤에 계산합니다.
예제
결과를 먼저 생각한 뒤 펼쳐 보세요. 맞혀 보기는 점수에 들지 않습니다.
다음 cleanInput(raw) 함수는 입력 칸의 value 문자열을 받아 앞뒤 공백을 깎고, 빈 줄이면 null을, 글자가 있으면 그 글자를 돌려줍니다. 세 번 부른 출력은 무엇일까요?
function cleanInput(raw) {
const text = raw.trim();
if (text === '') return null;
return text;
}
console.log(cleanInput(' '));
console.log(
cleanInput(' 우유 사기 '),
);
console.log(cleanInput('0'));
결과 보기
null
우유 사기
0' '는.trim()뒤에''가 되어null을 돌려줍니다.' 우유 사기 '는 앞뒤 공백이 깎여'우유 사기'가 되고,'0'은 빈 문자열이 아니므로'0'그대로 남습니다.
자주 틀리는 곳
submit리스너에서event.preventDefault()를 빼먹는다: 할 일을 추가하자마자 페이지가 깜빡이며 새로고침되고, 방금 추가한 할 일과 콘솔 출력이 순식간에 사라집니다.input.value를 숫자인 줄 알고 바로+로 더한다:input.value는 늘 문자열이므로'1000' + 500이'1000500'이 됩니다. 숫자로 쓸 때는Number(input.value)를 씁니다.- 입력 칸의 글자를
input.textContent로 읽으려 한다:<input>요소는 닫는 태그가 없는 빈 요소라textContent가 언제나''입니다. 입력 칸의 글자는 읽을 때도 비울 때도 **input.value**를 씁니다. - 공백만 친 입력을 거르지 않는다:
input.value === ''만 검사하면 스페이스바만 여러 번 친' '가 통과해 빈 할 일 줄이 만들어집니다. 반드시 **input.value.trim() === ''**로 검사합니다.
확인 문제
<form>안의 제출 단추에'click'리스너를 다는 대신<form>에'submit'리스너를 달고 첫 줄에event.preventDefault()를 적는 까닭 두 가지를 쓰세요.
정답
첫째, 마우스로 단추를 누를 때와 입력 칸에서 Enter를 누를 때를 한 리스너로 모두 받을 수 있습니다. 둘째, event.preventDefault()가 폼 제출 시 페이지가 새로고침되어 상태가 초기화되는 기본 동작을 막아 줍니다.
- 사용자가 입력 칸(
input)에' 산책하기 '를 쳤습니다. 앞뒤 공백을 뺀 글자를text상수에 담고, 이어서 입력 칸을 비우는 두 줄을 쓰세요.
정답
첫 줄은 text = input.value.trim()이고, 둘째 줄은 input.value = ''입니다.
value="4"인 숫자 입력 칸 요소q에서console.log(q.value + 1);을 실행하면 무엇이 찍히며,5가 찍히게 하려면 어떻게 고쳐야 하나요?
정답
q.value가 문자열 '4'이므로 '41'이 찍힙니다. 5가 찍히게 하려면 Number(q.value) + 1로 고칩니다.