폼(form) 제어를 위한 3가지 유용한 팁

Kimaramy·2019년 12월 11일
7

프론트엔드 개발

목록 보기
3/14
post-thumbnail

1. form 객체 내부 요소에 접근하기

body 객체(document.body)와 마찬가지로, 폼(form)은 document의 직계 객체로 설계되어 있습니다. 차이점이 있다면, 문서 내에 폼이 여러 개가 될 수 있으므로 document.forms 유사배열(HTMLCollection)에 담기게 됩니다. 그래서 폼 요소를 DOM으로 접근 후, 이어서 폼 내부 인터페이스 요소들을 name 또는 type의 속성값을 식별자로 접근할 수 있습니다. 이를 이용한 상세 접근법은 다음의 2가지입니다.

1-1. 점 표기법(Dot notation)

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 객체 내 해당 폼 또는 하위 컨트롤 요소의 키네임이 되기 때문입니다.

1-2. 괄호 표기법(Bracket notation)

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)를 주지 않아도 됩니다. 대신, nametype 속성을 존재 목적에 맞게 작성해주는 습관을 들여야겠습니다.

2. submit 이벤트와 기본 동작 방지

폼 요소의 이벤트는 내부 <button> 또는 <input>type 속성에 따릅니다. 폼은 서버에 작성된 데이터를 보내기 위함이므로 submit 이벤트가 거의 사용되며, type="submit"의 인터페이스를 클릭하면 폼 내부에 입력된 모든 내용(value)을 서버에 제출하는 동작이 일어납니다. 이는 submit의 기본(default) 이벤트입니다.

이때, 이벤트를 등록하는 객체는 버튼이 아닌 폼 요소에 지정해야 합니다. 이렇게 하면 인터페이스를 감싼 <form>은 submit 이벤트 함수가 바인딩 된 대상(this) - event.currentTarget이 되며, submit 버튼은 실제 이벤트가 발생하는 대상 - event.target이 됩니다.

참고: 이벤트 위임(Event Delegation)

하지만 데이터를 서버로 전송하지 않고 다른 목적으로 사용하려면, 이 기본 이벤트를 취소해줘야 합니다. 이를 위해서 리스너 함수에 매개 변수로 들어오는 event 객체에 다음의 API 메소드를 사용합니다.

event.preventDefault()

단, 해당 이벤트가 취소 가능한 이벤트여야 하며, 이는 event.cancelable로 확인 가능합니다.

3. 자동완성 해제

먼저, 자동완성 기능은 해당 브라우저의 설정에서 제어할 수 있습니다. 하지만 이와 상관없이, 제작자는 폼 태그 내의 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

참고


profile
스타트업에서 Software Engineer로 일하고 있습니다

2개의 댓글

comment-user-thumbnail
2021년 12월 2일

submit 이벤트 동작방식을 찾고있었는데, 덕분에 많이 배워갑니다. 감사합니다 : )

답글 달기
comment-user-thumbnail
2022년 3월 5일

정리가 깔끔하게 잘 되어 있어서 쉽게 배우고 갑니다 감사합니다!! :D

답글 달기