インタラクティブフォームの構築
JSを持つことは、我々の人生を単純化するつもりです.我々がしたことのいくつかが標準でなくて、彼らがWebKitブラウザーの外で働くつもりでなかったので、それはかなり我々のブラウザー支持を広げます.
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で必要な変更を処理することです.
これにはいくつかの利点があります.
パスワードを隠す
元のフォームでは、我々は非標準との表示/非表示のパスワード機能を扱う
-webkit-text-security
. それはコードが自然な順序でない理由の1つであり、非標準的な機能として、それは私たちのフォームの範囲を制限しました.現時点では、JavaScriptを使用してその機能を処理し、幸運に私たちのため、それはかなり簡単なことです:我々は、チェックボックスにイベントリスナーを添付し、変更するたびに、我々は更新されます
type
パスワードの入力text
を返します.password
を返します.// show password interactivity
document.querySelector("#show-password").addEventListener("input", function() {
document.querySelector("#password").type = this.checked ? "text" : "password";
});
私たちはif...else
構造体ですが、三項演算子はコードをかなり簡素化します.入力スタイルの拡張
チュートリアルの次の(および最後の)手順では、要素イベント(ホバー、フォーカスなど)のいくつかのスタイルを追加しますが、いくつかのケースはCSSで完全にカバーできません.
主なものは、入力がフォーカスを持つときにラベルテキストをスタイリングすることです.私たちは
:focus-within
ラベルに適用されますがnot supported by all browsers . 他のフォームでは、それは“簡単”でした:我々は入力とテキストの順序を交換し、兄弟セレクタを使用することができました.入力が-または紛失したかどうかチェックする必要があります
label
: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));
}
次のステップでは、使用します:focus-within
このJavaScriptのスニペットに“フォールバック”オプションとして.フォームの検証
理想的には、検証はフロントエンドとバックエンドの両方で起こります.バックエンド側の検証は、このチュートリアルの範囲外ですので、私はフロントエンドに焦点を当てます.ではなく、
ブラウザでフロントエンドの検証を委任していますが、HTMLの検証をサポートしていないブラウザを見つける場合、JavaScriptのロジックを追加することもできます.私たちのいくつかの基本的な検証ではなく、複雑なだけで、最小の長さをチェックする
minlength
しかし、テスト用には、以下を追加しません):// 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);
エラーが発生した場合、フォームは送信されません(event.preventDefault()
では、エラーメッセージを表示します(フォームに追加しました).検証の一部として、我々はまた、
error-state
フィールドのラベルへのクラス.そのように、我々は我々が欲しい(しかし、我々のケースでは、赤い境界線とテキストで)間違ったフィールドを整えることもできますこのエラー状態は、入力が変更されるたびに削除されます.キャラクターアニメーション
最後に-最後に!本当の楽しい部分.私たちのフォームをユニークにするもの:前のセクションで作成したCSS文字のアニメーション.
文字で多くのことができます.
正しいアニメーション
スマイルを調整するのは無効なフィールドの数に依存し、我々は口のサイズと位置を変更することによってそれを達成する
div
. 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%;
}
これはCSS + JSのうちの25行(口の中にはすでに11が存在する)です.表示/非表示のパスワードアニメーション
目を閉じるには、「表示パスワード」チェックボックス変更イベント(余分なCSSを追加)を処理するために、既存のコードに1行のコードを追加する必要があります.
document.querySelector(".eyes").className = `eyes ${this.checked && " closed"}`;
figure .head .eyes.closed::before,
figure .head .eyes.closed::after {
height: 0.125rem;
animation: none;
}
それはそんなに悪くなかった.では、なぜ何か余分な追加?ユーザー名フィールドとして目の動きを追加しましょう!テキストを書く
特にこのフォントは少しトリッキーなので、私が選んだフォントはモノスペースではありません.これは、異なる文字が異なる幅(例えば、私が同じスペースで合うだけである間、私がテキストボックスに収まるように)を持っていることを意味します、そして、我々は目がどれくらいの目を動かす必要があるかについて、目玉をする必要があります.
すべてのユーザーがすべてのIまたはMのすべてのユーザー名を持つというわけではありません、そして、一般に、他の手紙の幅は、それらの2つの間の何かであるでしょう.それで、通常、25 - 30文字がテキストフィールドに合うふりをしましょう.27?
それから私たちの論理は次のようになります.
// 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 :
つの最後のステップ:いくつかのスタイルを調整するので、JavaScriptに依存関係がなく、いくつかの追加のものをきれいにします.
Reference
この問題について(インタラクティブフォームの構築), 我々は、より多くの情報をここで見つけました https://dev.to/alvaromontoro/building-an-interactive-form-interactivity-49h7テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol