body 객체(document.body)와 마찬가지로, 폼(form)은 document의 직계 객체로 설계되어 있습니다. 차이점이 있다면, 문서 내에 폼이 여러 개가 될 수 있으므로 document.forms 유사배열(HTMLCollection)에 담기게 됩니다. 그래서 폼 요소를 DOM으로 접근 후, 이어서 폼 내부 인터페이스 요소들을 name
또는 type
의 속성값을 식별자로 접근할 수 있습니다. 이를 이용한 상세 접근법은 다음의 2가지입니다.
document.formName.elementName || elementTypeName
이 방식은 document 객체의 직계로 form 속성에 정의된 name의 값이 form 요소의 객체명이 되므로 이를 통해 접근하는 것입니다. 코드로 살펴보면 다음과 같습니다.
<form name="signUp" id="sign-up">
<input type="text" name="newId" placeholder="아이디를 입력하세요." />
<input type="submit" value="등록"/>
</form>
<script>
// 폼 객체 'signUp'의 name="newId"인 요소 지정
const signUpFormTxt = document.signUp.newId;
// 폼 객체 'signUp'의 type="submit"인 버튼 요소 지정
const signUpFormSbmt = document.signUp.submit;
</script>
비교적 간결합니다. 하지만 그만큼 네이밍이 직관적이어야 한다는 고충도 있습니다. 이 방식은 폼이 단일하거나 구조가 단순할 경우 적합할 것 같습니다.
name
속성값은 가능한 한 camelCase 방식으로 작성해야 합니다. 이는 DOM 객체 내 해당 폼 또는 하위 컨트롤 요소의 키네임이 되기 때문입니다.
document.forms['formName'].elements['elementName || elementTypeName']
이 방식은 document 직계 객체인 forms를 통해 접근합니다. forms 객체의 배열 값에 form에서 지정한 name 속성의 값을 지정하면 해당하는 form에 접근할 수 있습니다.
<form name="signUp" id="sign-up">
<input type="text" name="newId" placeholder="아이디를 입력하세요." />
<input type="submit" value="등록"/>
</form>
<script>
// 폼 객체 'signUp'의 name="newId"인 요소 지정
const signUpFormTxt = document.forms['signUp'].elements['newId'];
// 폼 객체 'signUp'의 type="submit"인 요소 지정
const signUpFormSbmt = document.forms['signUp'].elements['submit'];
</script>
비교적 구조적이라 명확합니다. 문서 내에 폼이 여러 개 있거나 내부 컨트롤이 많을 경우 적합할 것 같습니다.
어찌 되었든 DOM 노드를 접근하기 위해 요소에 일일이 Id(class)를 주지 않아도 됩니다. 대신, name
과 type
속성을 존재 목적에 맞게 작성해주는 습관을 들여야겠습니다.
폼 요소의 이벤트는 내부 <button>
또는 <input>
의 type
속성에 따릅니다. 폼은 서버에 작성된 데이터를 보내기 위함이므로 submit 이벤트가 거의 사용되며, type="submit"
의 인터페이스를 클릭하면 폼 내부에 입력된 모든 내용(value)을 서버에 제출하는 동작이 일어납니다. 이는 submit의 기본(default) 이벤트입니다.
이때, 이벤트를 등록하는 객체는 버튼이 아닌 폼 요소에 지정해야 합니다. 이렇게 하면 인터페이스를 감싼 <form>
은 submit 이벤트 함수가 바인딩 된 대상(this) - event.currentTarget
이 되며, submit 버튼은 실제 이벤트가 발생하는 대상 - event.target
이 됩니다.
하지만 데이터를 서버로 전송하지 않고 다른 목적으로 사용하려면, 이 기본 이벤트를 취소해줘야 합니다. 이를 위해서 리스너 함수에 매개 변수로 들어오는 event 객체에 다음의 API 메소드를 사용합니다.
event.preventDefault()
단, 해당 이벤트가 취소 가능한 이벤트여야 하며, 이는 event.cancelable
로 확인 가능합니다.
먼저, 자동완성 기능은 해당 브라우저의 설정에서 제어할 수 있습니다. 하지만 이와 상관없이, 제작자는 폼 태그 내의 autocomplete
속성으로 강제 토글(toggle)할 수 있습니다. 기본값은 autocomplete="on"
이지만 보안을 위해서 이 기능을 강제로 막고 싶을 때는 off로 설정하면 됩니다. 아래와 같이 폼 태그에 설정하면 포함된 모든 요소는 자동완성 기능을 막게 됩니다.
<form name="signUp" autocomplete="off">...</form>
여기까지 내용을 종합해 간단한 폼을 만들었습니다.
<form action="" method="POST" name="userComment" autocomplete="off">
<label for="textarea">댓글</label>
<textarea name="textarea" cols="80" rows="8"></textarea>
<button type="submit">등록</button>
</form>
<script>
// 폼(form) 객체만 지정해주면 내부 인터페이스는 name / type 으로 접근 가능
const cmntForm = document.forms['userComment'];
cmntForm.addEventListener('submit', function(event){
event.preventDefault();
this.textarea.value = ""; // this === cmntForm
});
</script>
원본 : Form submit event and prevent default | Codepen
submit 이벤트 동작방식을 찾고있었는데, 덕분에 많이 배워갑니다. 감사합니다 : )