상호 작용 양식 만들기: 상호 작용

27327 단어 tutorialhtmlwebdevcss
원시 표의 주요 도전은 상호작용을 처리하는 것이다.JavaScript가 없으면, 코드를 읽고 조직하기 어려운 해커와 기교에 도움을 청해야 합니다.
JS를 보유하면 우리의 생활이 간소화될 것이다.이것은 또한 우리의 브라우저 지원을 크게 확장할 것이다. 왜냐하면 우리가 하는 일들은 표준적이지 않기 때문이다. 그들은 웹 Kit 브라우저 외에서 일을 할 수 없기 때문이다. (지금은 절대 다수이지만, 여전히 그렇다.)

Note: I am not going to use any JS framework or transpiler, and stick with vanilla JavaScript for this form. It makes the snippet lighter, cleaner (that's my opinion), and framework-agnostic. If you are using a framework/transpiler, you can easily adapt the code to it.


사용 클래스


사용자 작업에서 트리거되는 많은 이벤트에는 색상, 위치 또는 크기 변경이 포함됩니다.함수에 직접 변경 사항을 적용하는 것과 달리 가능한 경우 요소에 클래스를 적용하고 CSS에서 필요한 변경 사항을 처리합니다.
다음과 같은 이점이 있습니다.
  • 더 깨끗한 JavaScript: 코드는 주로 이벤트 발생 시 클래스 추가/삭제를 포함합니다.
  • 분리 작업: JavaScript는 로직을 담당하고 CSS는 스타일을 담당합니다.
  • 유지 보수 및 수정이 용이함: 흐트러짐 없는 JS 코드로 이후의 변경 및 유지 보수를 간소화합니다.
  • 하지만 작은 변화부터...유일하게 교대할 필요가 없는 것은

    암호 표시 / 숨기기


    원본 폼에서 우리는 비표준 -webkit-text-security 을 사용하여 암호 표시/숨기기 기능을 처리합니다.이것은 코드가 자연 순서에 부합되지 않는 원인 중의 하나이며, 비표준 기능으로서 우리의 형식을 제한한다.
    현재로서는 JavaScript를 사용하여 이 기능을 처리하는 것이 가장 좋습니다. 다행히도 이것은 상당히 간단한 일입니다. 이벤트 탐지기를 체크 상자에 추가합니다. 이 기능이 변경될 때마다 비밀번호를 입력한 type (체크 상자) 또는 text (선택하지 않은 경우) 로 업데이트합니다.
    // show password interactivity
    document.querySelector("#show-password").addEventListener("input", function() {
      document.querySelector("#password").type = this.checked ? "text" : "password";
    });
    
    우리는 본래 password 구조를 사용할 수 있었지만, 삼원 구조는 코드를 크게 간소화하여 여전히 작동할 수 있고 읽을 수 있다.

    입력 스타일 확장


    이 강좌의 다음 (또는 마지막) 단계에서, 우리는 요소 이벤트에 스타일(스톱, 초점 등)을 추가할 것이지만, 어떤 경우에는 CSS만 사용해서 완전히 덮어쓸 수 없습니다.
    주요 방법은 포커스를 입력할 때 라벨 텍스트의 스타일을 설정하는 것이다.우리는 if...else 라벨에 적용할 수 있지만, 그것은 not supported by all browsers 이다.다른 형식에서는 간단합니다. 입력과 텍스트의 순서를 교환하고 동급 선택기를 사용할 수 있습니다.
    입력이 포커스를 얻거나 잃어버렸는지 확인하고 :focus-within 를 포함하는 클래스를 추가해야 합니다.
    const labels = document.querySelectorAll("#login-form label input");
    for (let x = 0; x < labels.length; x++) {
        labels[x].addEventListener("focus", function() {
        this.parentNode.classList.add("state-focus");
      });
    
      labels[x].addEventListener("blur", function() {
        this.parentNode.classList.remove("state-focus");
      });
    }
    
    그리고 우리는 그 반의 특례가 있을 것이다.레이블 텍스트와 입력 테두리를 주 색상의 연한 버전으로 만듭니다.
    label.state-focus span {
      color: hsl(var(--fgColorH), calc(var(--fgColorS) * 2), calc(var(--fgColorL) * 1.15));
    }
    
    label input:focus,
    label.state-focus input,
    label.state-focus span.checkbox-label::before {
      border-color: hsl(var(--fgColorH), calc(var(--fgColorS) * 2), calc(var(--fgColorL) * 1.15));
    }
    
    label.state-focus input[type="checkbox"]:checked + span.checkbox-label::after {
      background: hsl(var(--fgColorH), calc(var(--fgColorS) * 2), calc(var(--fgColorL) * 1.15));
    }
    
    다음 단계에서는 JavaScript 세션에 대한 [fallback] 옵션으로 label 을 사용합니다.

    양식 검증


    이상적인 상황에서 검증은 전단과 후단에서 진행해야 한다.백엔드 검증은 본 강좌의 범위 내에 있지 않기 때문에 저는 백엔드를 중점적으로 소개할 것입니다...하지만 너무 많이 하지 마세요. -/
    우리는 브라우저의 프런트엔드 인증을 부여하고 있지만, 브라우저가 HTML 인증을 지원하지 않는 것을 발견하지 못하도록 자바스크립트에 논리를 추가할 수 있습니다.우리는 기본적인 검증을 진행할 것이다. 그렇게 복잡하지 않고 최소 길이만 검사할 뿐이다. :focus-within 검증을 할 수도 있지만 테스트 목적으로 추가하지 않을 것이다.
    // form submission = validation
    document.querySelector(".login-form").addEventListener("submit", function(e) {
      let errorMessage = "";
      const error = document.querySelector("#error-message");
      const username = document.querySelector("#username");
      const password = document.querySelector("#password");
    
      error.textContent = "";
    
      // check password length
      if (password.value.length < 8) {
        errorMessage = "Password is mandatory";
        password.parentNode.classList.add("state-error");
        password.focus();
      // check email length
      } else if (username.value.length < 5) {
        errorMessage = "Username is too short (min 5 chars)";
        username.parentNode.classList.add("state-error");
        username.focus();
      } 
    
      if (errorMessage != "") {
        error.textContent = errorMessage;
        e.preventDefault();
      }
    });
    
    // remove state error on field change
    function removeError(e) {
        e.target.parentNode.classList.remove("state-error");
      document.querySelector("#error-message").textContent = "";
    }
    document.querySelector("#password").addEventListener("input", removeError);
    document.querySelector("#username").addEventListener("input", removeError);
    
    오류가 있으면 양식이 전송되지 않습니다(minlength 이 작업을 수행합니다), 양식에 방금 추가한 오류 메시지가 표시됩니다.

    검증의 일부로서, 우리는 필드의 탭에 event.preventDefault() 클래스를 추가할 것이다.이렇게 하면 우리는 자신의 뜻에 따라 잘못된 필드를 양식화할 수 있다 (이 예에서 빨간색 테두리와 텍스트를 사용한다)입력이 변경되면 이 오류 상태가 삭제됩니다.

    캐릭터 애니메이션 설정


    마지막정말 재미있는 부분.이것은 우리의 표를 독특하게 만들 것이다. 우리가 지난 절에서 만든 CSS 캐릭터의 애니메이션.
    캐릭터는 많은 일을 할 수 있다.
  • 필드가 정확할 때 웃음을 더 크게 만든다.
  • 암호 표시 상자를 선택하면 눈을 감습니다.
  • "비밀번호 보이기"상자를 선택하면 손으로 눈을 가린다. (다린 센니프가 그의 유명한 눈사람 형태에서 한 것처럼)
  • 오류/수정 필드에 따라 눈썹 애니메이션을 설정합니다.
  • 텍스트의 경로를 따라 눈을 움직인다 something similar in a previous form.
  • 텍스트 입력과 함께 머리 전체를 이동합니다(Darin Senneff의 기능은 다음과 같습니다.)
  • 오류가 발생하면 입의 표정이 다르다.
  • 만약 입력이 초점에 맞지만 X초 후에 아무런 내용도 쓰지 않으면 캐릭터를 짜증나게 한다.
  • 모든 필드가 유효하면 오색 종이 부스러기/모임 모자를 떨어뜨립니다.
  • ...네가 상상할 수 있는 어떤 것도
  • 이것은 단지 건의가 있는 입위 명단일 뿐이다.그 중 많은 것은 합병할 수 있지만, 그 중 일부는 목록의 다른 부분과 호환되지 않는다.추가할 것을 선택하는 것은 당신의 결정입니다.이 프레젠테이션에서는 다음 중 몇 개만 추가합니다.
  • 한 필드가 정확할 때 웃음을 더 크게 만든다.
  • 모든 필드가 정확할 때 웃음을 더욱 빛나게 한다.
  • 암호 표시 상자를 선택하면 눈을 감습니다.
  • 애니메이션이 맞다면 웃어주세요.


    미소를 조정하는 것은 잘못된 필드의 수량에 달려 있으며, 우리는 입의 크기와 위치를 바꾸어 실현한다error-state.클래스 사용(다시!)을 통해 JavaScript 코드는 간단합니다.우리는 우리가 원하는 것을 얻을 때까지 입의 높이/너비/꼭대기 위치를 약간 조정해야 한다.
    const invalidFields = document.querySelectorAll("input:invalid").length;
    document.querySelector(".mouth").className = `mouth errors-${invalidFields}`;
    
    /* already existing default state: 2 errors */
    figure .head .mouth {
      border: 0.125rem solid transparent;
      border-bottom: 0.125rem solid var(--borderDarker);
      width: 25%;
      border-radius: 50%;
      transition: all 0.333s;
      top: 75%;
      left: 50%;
      height: 10%;
    }
    
    /* only one input is invalid: bigger smile */
    figure .head .mouth.errors-1 {
      top: 61%;
      width: 35%;
      height: 40%;
    }
    
    /* no inputs are invalid: the biggest smile */
    figure .head .mouth.errors-0 {
      top: 53%;
      width: 45%;
      height: 55%;
    }
    
    이것은 25줄의 CSS+JS(그중 11줄은 이미 구강에 존재한다)입니다. 우리는 다음과 같은 효과를 얻었습니다.

    암호 애니메이션 표시 / 숨기기


    눈을 감으려면 암호 표시 확인란 변경 이벤트를 처리하기 위해 이미 존재하는 코드에 코드를 한 줄 추가해야 합니다(추가 CSS 추가).
    document.querySelector(".eyes").className = `eyes ${this.checked && " closed"}`;
    
    figure .head .eyes.closed::before,
    figure .head .eyes.closed::after {
      height: 0.125rem;
      animation: none;
    }
    
    그렇게 나쁘진 않죠?그렇다면 왜 추가 내용을 추가하지 않습니까?사용자 이름 필드에 입력할 때 눈의 이동을 추가합니다!

    본문을 따라 쓰다


    이것은 좀 복잡하다. 특히 내가 선택한 글씨체는 단일 공백이 아니기 때문이다.이것은 서로 다른 문자가 서로 다른 폭을 가지고 있다는 것을 의미한다. 예를 들어 텍스트 상자에는 60개의 I를 수용할 수 있고 같은 공간에는 12개의 M만 수용할 수 있다. 우리는 눈을 얼마나 움직여야 하는지 주목해야 한다.
    모든 사용자의 사용자 이름이 I 또는 M인 것은 아닙니다. 일반적으로 다른 문자의 너비는 이 두 글자 사이입니다.따라서 텍스트 필드에 보통 25-30개의 알파벳을 수용할 수 있다고 가정해 봅시다.27?
    그러면 우리의 논리는 다음과 같다.
  • 사용자 이름 입력이 초점을 얻으면 눈을 아래로 이동(캐릭터가 보는 척)
  • 사용자 이름 입력이 초점을 잃으면 눈을 수직으로 복원합니다.
  • 최대 27자를 고려하여 눈을 왼쪽으로 "값의 길이-14"픽셀을 이동합니다.
  • 코드는 다음과 같습니다(CSS를 변경할 필요가 없음).
    // move eyes following username input 
    function moveEyes(e) {
      const eyes = document.querySelector(".eyes");
      const length = e.target.value.length;
      // this is a bit trickier because the eyes already have a translation!
      eyes.style.transform = `translate(calc(-50% + ${Math.min(length/2 - 7, 7)}px), calc(-50% + 0.25rem))`;
    }
    document.querySelector("#username").addEventListener("focus", moveEyes);
    document.querySelector("#username").addEventListener("input", moveEyes);
    document.querySelector("#username").addEventListener("blur", function() {
      document.querySelector(".eyes").style.transform = "translate(-50%, -50%)";
    });
    

    Note: the transform calculation is a bit messy because the eyes' div already has a transformation applied to it. I tried using margins, but then the transition is not as smooth and nice.


    이것은 현재 표입니다. JSFiddle:
    마지막 단계: 자바스크립트에 의존하지 않고 추가 물건을 정리할 수 있도록 스타일을 조정합니다.

    좋은 웹페이지 즐겨찾기