일반 JavaScript 양식 유효성 검사

주어진 웹 응용 프로그램이나 사이트의 백엔드 부분에서 수없이 검증을 실행하고 싶지 않을 때, 전방 자바스크립트 검증은 하늘이 내린 좋은 기회입니다.이 설명서에서는 vanilla JavaScript를 사용하여 프런트엔드 인증을 수행하는 방법에 대해 설명합니다.
우리는 이 점을 실현하기 위해 틀이나 화려한 플러그인을 필요로 하지 않는다.만약 당신이 자신이 한 번 또 한 번 일을 하고 있다는 것을 발견한다면, 이러한 방법들은 쓸모가 있을 것이다. 그러나 나의 가장 좋은 건의는 가능한 한 열심히 일하는 것에서 시작하고, 거기에서 당신의 의존성을 넓히는 것이다.
저는 aCodePen에 이 모든 것을 창설하여 당신의 관람의 즐거움을 만족시켰습니다.만약 네가 따르기로 결정한다면, 너는 그것과/또는 너의 판본을 나의 판본과 비교할 수 있다.
검증이 정상적으로 작동하려면 기본 HTML과 CSS가 필요합니다.이 설명서는 JavaScript에 초점을 맞추기 때문에 HTML 및 CSS를 빠르게 탐색합니다.

HTML
<div class="container">
  <h2 class="title">Create a new account</h2>
  <form action="#" class="form">

    <div class="input-group">
      <label for="username" class="label">Username</label>
      <input id="username" placeholder="webcrunch" type="text" class="input">
      <span class="error-message"></span>
      <svg class="icon icon-success hidden hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
      </svg>

      <svg class="icon icon-error hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
      </svg>
    </div>

    <div class="input-group">
      <label for="email" class="label">Email</label>
      <input id="email" type="email" class="input" autocomplete placeholder="[email protected]">
      <span class="error-message"></span>
      <svg class="icon icon-success hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
      </svg>

      <svg class="icon icon-error hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
      </svg>
    </div>

    <div class="input-group">
      <label for="password" class="label">Password</label>
      <input id="password" type="password" class="input">
      <span class="error-message"></span>
      <svg class="icon icon-success hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
      </svg>

      <svg class="icon icon-error hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
      </svg>
    </div>

    <div class="input-group">
      <label for="password_confirmation" class="label">Password Confirmation</label>
      <input id="password_confirmation" type="password" class="input">
      <span class="error-message"></span>
      <svg class="icon icon-success hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
      </svg>

      <svg class="icon icon-error hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
      </svg>
    </div>

    <input type="submit" class="button" value="Create account">

  </form>
</div>

<div class="promo">👋 Check out my <a href="https://web-crunch.com" target="_blank">blog</a> or my <a href="https://youtube.com/webcrunch">YouTube channel</a> to learn more about how I made this.</div>
여기에 표시된 UI는 기본 가상 계정 설정 양식입니다.이것은 아마도 당신이 처음으로 온라인으로 서비스나 응용 프로그램을 등록할 때 본 폼일 것입니다.이러한 입사 체험에서 많은 응용 프로그램 소유자/운영자들은 유효한 데이터만 입력하여 자신의 생활을 더욱 가볍게 하기를 원한다.만약 대중을 대상으로 하는 사용자가 내부 팀의 관심 없이 성공적으로 승선할 수 있다면 이것이 주요 목표이다.
표에는 username, email, passwordpassword_confirmation 필드가 포함되어 있습니다.필드마다 '상태' 를 설명하는 아이콘이 있고, 발생할 수 있는 오류를 표시하는 빈 div도 있습니다.
JavaScript를 사용하여 이러한 필드, 아이콘 및 요소에 직접 적용합니다.

CSS
* {
    box-sizing: border-box;
}

body {
  background-color: blueviolet;
}

.title {
  margin-bottom: 2rem;
}

.hidden {
  display: none;
}

.icon {
  width: 24px;
  height: 24px;
  position: absolute;
  top: 32px;
  right: 5px;
  pointer-events: none;
  z-index: 2;

  &.icon-success {
    fill: green;
  }

  &.icon-error {
    fill: red;
  }
}

.container {
  max-width: 460px;
  margin: 3rem auto;
  padding: 3rem;
  border: 1px solid #ddd;
  border-radius: .25rem;
  background-color: white;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}

.label {
  font-weight: bold;
  display: block;
  color: #333;
  margin-bottom: .25rem;
  color: #2d3748;
}

.input {
  appearance: none;
  display: block;
  width: 100%;
  color: #2d3748;
  border: 1px solid #cbd5e0;
  line-height: 1.25;
  background-color: white;
  padding: .65rem .75rem;
  border-radius: 0.25rem;
  box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06);

  &::placeholder {
    color: #a0aec0;
  }

  &.input-error {
    border: 1px solid red;

    &:focus {
      border: 1px solid red;
    }
  }

  &:focus {
    outline: none;
    border: 1px solid #a0aec0;
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
    background-clip: padding-box;
  }
}

.input-group {
  margin-bottom: 2rem;
  position: relative;
}

.error-message {
  font-size: .85rem;
  color: red;
}

.button {
  background-color: blueviolet;
  padding: 1rem 2rem;
  border: none;
  border-radius: .25rem;
  color: white;
  font-weight: bold;
  display: block;
  width: 100%;
  text-align: center;
  cursor: pointer;

  &:hover {
    filter: brightness(110%);
  }
}

.promo {
  color: white;
  opacity: .75;
  margin: 1rem auto;
  max-width: 460px;
  background: rgba(255, 255, 255, .2);
  padding: 20px;
  border-radius: .25rem;

  a {
    color: white;
  }
}
CSS는 이 양식을 강화하고 가용성을 높이는 데 사용됩니다.나의 최종 디자인은 오류가 발생했는지 여부에 따라 입력한 오른쪽에 아이콘을 표시하는 것이다.이 필드가 유효하면 녹색 체크 표시를 표시합니다.이 필드가 올바르지 않으면, 이 필드에 빨간색 테두리를 추가하고, 그 위에 십자 아이콘을 직접 표시합니다.
각 아이콘은 SVG 요소입니다.SVG는 확장성과 맞춤형 구성에 탁월합니다.CSS만 사용하면 각 SVG에 대해 이러한 특성을 변경할 수 있습니다.

JavaScript
지금은 주요 행사다.이와 유사한 문제를 해결하기 위해 JavaScript를 작성할 수 있는 수많은 방법이 있습니다.나는 대상을 향한 배경(Ruby)에서 더 많이 왔다. Ruby에서 접근 함수와 방법은 클래스 단계에서 이루어진다.JavaScript에서 이 점을 시뮬레이션하기 위해 서로 통신하는 방법을 포함하는 ES6 JavaScript 클래스를 만들었습니다.이렇게 하는 주요 목적은 앞으로 우리 사이트나 응용 프로그램의 다른 분야에서 재사용할 수 있도록 하는 것이다.
때때로 코드를 작성할 때, 너는 미래를 위해 계획을 세워서는 안 된다.이것은 당신이 작성할 때보다 더 많은 복잡성을 가져올 것입니다.다른 한편, 그 중 일부 유형의 방법을 다시 쓸 것이라고 확신한다면, 앞을 내다보는 것은 의미가 있다.나는 영상을 보고 모든 함수의 기능을 상세하게 토론할 것을 건의하지만, 지금은 여기가 마지막 코드이다.
class FormValidator {
  constructor(form, fields) {
    this.form = form
    this.fields = fields
  }

  initialize() {
    this.validateOnEntry()
    this.validateOnSubmit()
  }

  validateOnSubmit() {
    let self = this

    this.form.addEventListener('submit', e => {
        e.preventDefault()
        self.fields.forEach(field => {
        const input = document.querySelector(`#${field}`)
        self.validateFields(input)
      })
    })
  }

  validateOnEntry() {
    let self = this
    this.fields.forEach(field => {
      const input = document.querySelector(`#${field}`)

      input.addEventListener('input', event => {
        self.validateFields(input)
      })
    })
  }

  validateFields(field) {

    // Check presence of values
    if (field.value.trim() === "") {
      this.setStatus(field, `${field.previousElementSibling.innerText} cannot be blank`, "error")
    } else {
      this.setStatus(field, null, "success")
    }

    // check for a valid email address
    if (field.type === "email") {
      const re = /\S+@\S+\.\S+/
      if (re.test(field.value)) {
        this.setStatus(field, null, "success")
      } else {
        this.setStatus(field, "Please enter valid email address", "error")
      }
    }

    // Password confirmation edge case
    if (field.id === "password_confirmation") {
      const passwordField = this.form.querySelector('#password')

      if (field.value.trim() == "") {
        this.setStatus(field, "Password confirmation required", "error")
      } else if (field.value != passwordField.value) {
        this.setStatus(field, "Password does not match", "error")
      } else {
        this.setStatus(field, null, "success")
      }
    }
  }

  setStatus(field, message, status) {
    const successIcon = field.parentElement.querySelector('.icon-success')
    const errorIcon = field.parentElement.querySelector('.icon-error')
    const errorMessage = field.parentElement.querySelector('.error-message')

    if (status === "success") {
      if (errorIcon) { errorIcon.classList.add('hidden') }
      if (errorMessage) { errorMessage.innerText = "" }
      successIcon.classList.remove('hidden')
      field.classList.remove('input-error')
    }

    if (status === "error") {
      if (successIcon) { successIcon.classList.add('hidden') }
      field.parentElement.querySelector('.error-message').innerText = message
      errorIcon.classList.remove('hidden')
      field.classList.add('input-error')
    }
  }
}

const form = document.querySelector('.form')
const fields = ["username", "email", "password", "password_confirmation"]

const validator = new FormValidator(form, fields)
validator.initialize()

요점은 앞으로 더 많은 표에서 사용할 수 있도록 FormValidator 라는 새로운 ES6 클래스를 만들었다는 것이다.파일의 맨 밑에 있는 클래스를 초기화하는 점을 찾을 수 있습니다.
우리는 new 키워드를 호출해서 FormValidator 새로운 실례를 만듭니다.임의의 실례를 만들 수 있습니다.우리의 예 중에서 우리는 단지 하나의 예만 필요로 한다.내부에서 우리는 두 개의 매개 변수formfields를 전달했다.
HTML에서 form 클래스 이름을 사용하여 .form 요소를 조회하는 방법을 주의하십시오.또한 HTML에 입력된 각 속성id과 일치하는 새 필드 이름 배열을 전달했습니다.
그곳에서 나는 initialize() 함수를 호출했는데, 그것은 FormValidator 클래스 내부를 가리킨다.
...
  initialize() {
    this.validateOnEntry()
    this.validateOnSubmit()
  }
...

이 함수는 두 개의 부함수를 호출하는데, 그것들은 비슷한 일을 하지만, 서로 다른 입력 이벤트를 사용한다.
코드 중의 this 키워드는 FormValidator 클래스 자체를 가리킨다.언제든지, 우리는 클래스의 방법 this 을 호출하여 formfields 에 접근할 수 있습니다. 왜냐하면 우리는 그것들을 매개 변수로 전송하기 때문입니다.
ES6 클래스에 매개 변수를 전달할 때 constructor 방법을 만들었습니다.
class FormValidator {
  constructor(form, fields) {
    this.form = form
    this.fields = fields
  }
...
이것은 form 키워드 접근 클래스의 임의의 위치 fieldsthis 인자를 사용할 수 있도록 합니다.🎉

확인
양식이 모든 사람에게 적합하도록 하기 위해서, 나는 제출 활동과 관건적인 항목에 대해 검증을 진행하기로 결정했다.사용자가 '제출' 단추를 누르면 검증을 하고 입력할 때 검증을 할 것입니다.
제출 이벤트는 폼을 통해 위치를 정할 수 있습니다.
...
  validateOnSubmit() {
    let self = this

    this.form.addEventListener('submit', e => {
        e.preventDefault()
        self.fields.forEach(field => {
        const input = document.querySelector(`#${field}`)
        self.validateFields(input)
      })
    })
  }
...

내가 상술한 임무를 완성하기 위해 작성한 코드 탐지기 submit 사건을 반복해서 우리가 이전에 매개 변수로 클래스에 전달한 모든 fields 를 반복합니다.우리는 모든 필드를 조회하여 validateFields 라는 재사용 가능한 방법에 전달합니다.
제출 기반 검증과 매우 비슷하여 우리는 관건적인 항목에 대한 검증도 할 수 있다
...
  validateOnEntry() {
    let self = this
    this.fields.forEach(field => {
      const input = document.querySelector(`#${field}`)

      input.addEventListener('input', event => {
        self.validateFields(input)
      })
    })
  }
...

여기서, 우리는 먼저 모든 필드를 훑어본 다음에, 모든 입력에 대한 감청 input 사건을 대상으로 한다.이벤트를 트리거하면, 우리는 이전에 사용한 것과 같은 validateFields 방법으로 해당 필드를 검증할 것입니다.우리가 어떻게 변수를 전달하는지 주의해라. input실제 검증을 할 때, 우리는 입력한 모든 실례가 필요하다.
이 두 가지 방법에 대해 우리는 this와 관련된 일부 범위 문제를 해결해야 한다.사건 탐지기의 범위 내에서this의 의미는 새로운 범위를 도입하여 변화할 수 있다.이 문제를 해결하려면 이벤트 탐지기 밖에서 새로운 변수를 설명하고 인용할 수 있습니다.너는 아마도 이 변수self를 보게 될 것이다. 이제는 그것이 왜 존재하는지 알게 될 것이다.결국, 나는 사건 탐지기의 외부 범위에만 접근하고 싶다.
마지막으로 validateFields를 호출하여 이 코드로 가져옵니다.
...
validateFields(field) {

  // Check presence of values
  if (field.value.trim() === "") {
    this.setStatus(field, `${field.previousElementSibling.innerText} cannot be blank`, "error")
  } else {
    this.setStatus(field, null, "success")
  }

  // check for a valid email address
  if (field.type === "email") {
    const re = /\S+@\S+\.\S+/
    if (re.test(field.value)) {
      this.setStatus(field, null, "success")
    } else {
      this.setStatus(field, "Please enter valid email address", "error")
    }
  }

  // Password confirmation edge case
  if (field.id === "password_confirmation") {
    const passwordField = this.form.querySelector('#password')

    if (field.value.trim() == "") {
      this.setStatus(field, "Password confirmation required", "error")
    } else if (field.value != passwordField.value) {
      this.setStatus(field, "Password does not match", "error")
    } else {
      this.setStatus(field, null, "success")
    }
  }
}
...

필드가 비어 있으면 유효한 전자 우편 주소를 포함하고, 암호라면 암호 확인 필드와 일치하면 이 방법을 사용합니다.표를 사용할 때, 우리는 이 방법을 여러 번 호출했다.
이 함수 중의 새로운 함수 setStatus 를 알 수 있습니다.이 함수는 언급된 특정한 필드, 메시지, 상태 유형을 포함하는 매개 변수를 받아들인다.이런 상황에서 그것은 success 또는 error일 뿐이다.매개 변수를 설정하면 사용자가 폼과 상호작용할 때 새로운 상태를 사용자에게 되돌려주는 다른 작업을 수행할 수 있습니다.
setStatus(field, message, status) {
  const successIcon = field.parentElement.querySelector('.icon-success')
  const errorIcon = field.parentElement.querySelector('.icon-error')
  const errorMessage = field.parentElement.querySelector('.error-message')

  if (status === "success") {
    if (errorIcon) { errorIcon.classList.add('hidden') }
    if (errorMessage) { errorMessage.innerText = "" }
    successIcon.classList.remove('hidden')
    field.classList.remove('input-error')
  }

  if (status === "error") {
    if (successIcon) { successIcon.classList.add('hidden') }
    field.parentElement.querySelector('.error-message').innerText = message
    errorIcon.classList.remove('hidden')
    field.classList.add('input-error')
  }
}

이 함수에서, 우리 조회 HTML 에 이미 존재하는 모든 종류의 아이콘과 오류 메시지div.
"통과한 status""성공""또는""오류""에 따라 다른 UI를 표시하고 다른 UI를 재설정할 수 있습니다."

끝맺다
전단 검증은 결코 틀림없는 것이 아니다.불행하게도 나는 비열한 사람과 로봇이 사이트의 표를 자주 이용하기 때문에 앞에서 검증만 사용하는 것을 권장하지 않는다.대부분의 웹 사이트와 응용 프로그램은 데이터베이스에 해롭거나 불필요한 데이터가 존재하는 것을 원하지 않는다.
나는 네가 이 지침을 좋아하길 바란다.JavaScript 자습서와 설명서에 대한 자세한 내용은 모음집을 보고 적합한 내용을 찾아보는 것이 좋습니다.곧 더 많아질 거야!
Let's Build with JavaScript - 14 videos and counting

좋은 웹페이지 즐겨찾기