バニラJavaScriptとCSSでマルチステップフォームを作成する方法
マルチステップフォームは、フォームが大きく、多くのコントロールがある場合に適しています。モバイルデバイス上の非常に長いフォームをスクロールしたい人はいません。画面ごとにコントロールをグループ化することにより、長く複雑なフォームに記入する経験を向上させることができます。
しかし、最後にマルチステップフォームを開発したのはいつですか?それはあなたにとっても楽しく聞こえますか?考えるべきことがたくさんあり、管理する必要がある非常に多くの感動的な作品があるので、フォームライブラリや、すべてを処理するフォームウィジェットに頼ることであなたを責めることはありません。しかし、手作業でそれを行うことは、良い運動であり、基本を磨くための素晴らしい方法です。最初のマルチステップフォームをどのように作成したかを紹介します。それがどれほど親しみやすいかを見るだけでなく、私の仕事をさらに良くするために領域を見つけられることを願っています。
一緒に構造を通り抜けます。私たちの多くは、私たちの多くが最近の日に関係することができると思います。最初にベースラインHTML、CSS、およびJavaScriptを足場にし、次にアクセシビリティと検証に関する考慮事項を検討します。途中で参照したい場合は、最終コード用のGitHubリポジトリを作成しました。
サンプルコードを取得しますマルチステップフォームの構造
求人申請書には4つのセクションがありますが、最後には要約ビューがあり、ユーザーが提出する前にすべての回答を表示します。これを達成するために、HTMLを4つのセクションに分割します。各セクションはIDで識別され、ページの下部にナビゲーションを追加します。次のセクションでそのベースラインHTMLをお伝えします。
セクションを移動するようにユーザーをナビゲートすることは、それらがどのステップであるか、残っているステップ数の視覚インジケーターも含めることを意味します。このインジケータは、アクティブなステップまたはよりファンシーな進行状況バーのタイプのインジケーターに応じて更新する単純な動的テキストにすることができます。前者は物事をシンプルに保ち、フォームのマルチステップの性質に集中します。
構造と基本的なスタイルロジックにもっと焦点を当てますが、最後にコードスニペットと完全なコードへのリンクを提供します。
ページを保持するフォルダーを作成することから始めましょう。次に、index.htmlファイルを作成し、次のことを貼り付けます。
HTMLを開きます
コードを見ると、3つのセクションとナビゲーショングループが表示されます。セクションにはフォーム入力が含まれており、ネイティブフォームの検証はありません。これは、ネイティブフォームの検証が[送信]ボタンをクリックするとトリガーされるため、エラーメッセージの表示をより適切に制御できるようにするためです。
次に、styles.cssファイルを作成して、それに貼り付けます:オープンベーススタイル
<form > <section > <div > <div > <label for="name">Name <span style="color: red;">*</span></label> <input type="text" name="name" placeholder="Enter your name"> </div> <div > <label for="idNum">ID number <span style="color: red;">*</span></label> <input type="number" name="idNum" placeholder="Enter your ID number"> </div> </div> <div > <div > <label for="email">Email <span style="color: red;">*</span></label> <input type="email" name="email" placeholder="Enter your email"> </div> <div > <label for="birthdate">Date of Birth <span style="color: red;">*</span></label> <input type="date" name="birthdate" max="2006-10-01" min="1924-01-01"> </div> </div> </section> <section > <div > <label for="document">Upload CV <span style="color: red;">*</span></label> <input type="file" name="document" > </div> <div > <label for="department">Department <span style="color: red;">*</span></label> <select name="department"> <option value="">Select a department</option> <option value="hr">Human Resources</option> <option value="it">Information Technology</option> <option value="finance">Finance</option> </select> </div> </section> <section > <div > <label for="skills">Skills (Optional)</label> <textarea name="skills" rows="4" placeholder="Enter your skills"></textarea> </div> <div > <input type="checkbox" name="terms" > <label for="terms">I agree to the terms and conditions <span style="color: red;">*</span></label> </div> <button type="submit">Confirm and Submit</button> </section> <div > <button type="button" >Previous</button> <span ></span> <button type="button" >Next</button> </div> </form> <script src="script.js"></script>
ブラウザでHTMLファイルを開きます。現在のページインジケーターとナビゲーションを備えた次のスクリーンショットで2列のレイアウトのようなものを取得する必要があります。
バニラJavaScriptを使用して機能を追加しますここで、htmlおよびcssファイルと同じディレクトリにscript.jsファイルを作成し、次のJavaScriptを貼り付けます。
ベーススクリプトを開きます
このスクリプトは、フォームセクションのIDSに対応するフォームステップ値に応じて、セクションを表示および隠すメソッドを定義します。フォームの現在のアクティブセクションでStepInfoを更新します。この動的テキストは、ユーザーへの進行状況インジケーターとして機能します。
:root { --primary-color: #8c852a; --secondary-color: #858034; } body { font-family: sans-serif; line-height: 1.4; margin: 0 auto; padding: 20px; background-color: #f4f4f4; max-width: 600px; } h1 { text-align: center; } form { background: #fff; padding: 40px; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); display: flex; flex-direction: column; } .form-group { display: flex; gap: 7%; } .form-group > div { width: 100%; } input:not([type="checkbox"]), select, textarea { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; } .form-control { margin-bottom: 15px; } button { display: block; width: 100%; padding: 10px; color: white; background-color: var(--primary-color); border: none; border-radius: 4px; cursor: pointer; font-size: 16px; } button:hover { background-color: var(--secondary-color); } .group-two, .group-three { display: none; } .arrows { display: flex; justify-content: space-between align-items: center; margin-top: 10px; } #navLeft, #navRight { width: fit-content; } @media screen and (max-width: 600px) { .form-group { flex-direction: column; } }
上記のJavaScriptコードが行っていることをさらに深く掘り下げましょう。 updateStepVisibility()関数では、最初にすべてのセクションを非表示にして、きれいなスレートを持っています。
次に、現在アクティブなセクション:
を示します
次に、指標がフォームを介して進行するというテキストを更新します。
const stepInfo = document.getElementById("stepInfo"); const navLeft = document.getElementById("navLeft"); const navRight = document.getElementById("navRight"); const form = document.getElementById("myForm"); const formSteps = ["one", "two", "three"]; let currentStep = 0; function updateStepVisibility() { formSteps.forEach((step) => { document.getElementById(step).style.display = "none"; }); document.getElementById(formSteps[currentStep]).style.display = "block"; stepInfo.textContent = `Step ${currentStep + 1} of ${formSteps.length}`; navLeft.style.display = currentStep === 0 ? "none" : "block"; navRight.style.display = currentStep === formSteps.length - 1 ? "none" : "block"; } document.addEventListener("DOMContentLoaded", () => { navLeft.style.display = "none"; updateStepVisibility(); navRight.addEventListener("click", () => { if (currentStep < formSteps.length - 1) { currentStep++; updateStepVisibility(); } }); navLeft.addEventListener("click", () => { if (currentStep > 0) { currentStep--; updateStepVisibility(); } }); });
ページが読み込まれたときに何が起こるかを見てみましょう。最初のセクションにフォームが読み込まれたときに、最初に前のボタンを非表示にします:
formSteps.forEach((step) => { document.getElementById(step).style.display = "none"; });
次に、次のボタンをつかみ、現在のステップカウントを条件付きで増分するクリックイベントを追加し、UpdateStepVisibility()関数を呼び出します。これにより、表示される新しいセクションが更新されます。
document.getElementById(formSteps[currentStep]).style.display = "block";`
最後に、前のボタンをつかんで同じことをしますが、逆です。ここでは、ステップカウントを条件付きで減らし、updateStepVisibility()を呼び出しています:
stepInfo.textContent = `Step ${currentStep + 1} of ${formSteps.length}`;
処理エラー
navLeft.style.display = currentStep === 0 ? "none" : "block"; navRight.style.display = currentStep === formSteps.length - 1 ? "none" : "block";
の前に
を修正できるようにします。それが私たちの形で私たちがすることです。document.addEventListener("DOMContentLoaded", () => { navLeft.style.display = "none"; updateStepVisibility();
私たちの原則は、どのコントロールにエラーがあるかを明確に示し、意味のあるエラーメッセージを提供することです。ユーザーが必要なアクションを実行するときにエラーをクリアします。フォームに検証を追加しましょう。まず、必要な入力要素をつかみ、これを既存の要素に追加しましょう。
navRight.addEventListener("click", () => { if (currentStep < formSteps.length - 1) { currentStep++; updateStepVisibility(); } });
検証スクリプトを開く
<form >
<section >
<div >
<div >
<label for="name">Name <span style="color: red;">*</span></label>
<input type="text" name="name" placeholder="Enter your name">
</div>
<div >
<label for="idNum">ID number <span style="color: red;">*</span></label>
<input type="number" name="idNum" placeholder="Enter your ID number">
</div>
</div>
<div >
<div >
<label for="email">Email <span style="color: red;">*</span></label>
<input type="email" name="email" placeholder="Enter your email">
</div>
<div >
<label for="birthdate">Date of Birth <span style="color: red;">*</span></label>
<input type="date" name="birthdate" max="2006-10-01" min="1924-01-01">
</div>
</div>
</section>
<section >
<div >
<label for="document">Upload CV <span style="color: red;">*</span></label>
<input type="file" name="document" >
</div>
<div >
<label for="department">Department <span style="color: red;">*</span></label>
<select name="department">
<option value="">Select a department</option>
<option value="hr">Human Resources</option>
<option value="it">Information Technology</option>
<option value="finance">Finance</option>
</select>
</div>
</section>
<section >
<div >
<label for="skills">Skills (Optional)</label>
<textarea name="skills" rows="4" placeholder="Enter your skills"></textarea>
</div>
<div >
<input type="checkbox" name="terms" >
<label for="terms">I agree to the terms and conditions <span style="color: red;">*</span></label>
</div>
<button type="submit">Confirm and Submit</button>
</section>
<div >
<button type="button" >Previous</button>
<span ></span>
<button type="button" >Next</button>
</div>
</form>
<script src="script.js"></script>
ログイン後にコピーログイン後にコピーログイン後にコピー
検証スクリプトを開く
<form > <section > <div > <div > <label for="name">Name <span style="color: red;">*</span></label> <input type="text" name="name" placeholder="Enter your name"> </div> <div > <label for="idNum">ID number <span style="color: red;">*</span></label> <input type="number" name="idNum" placeholder="Enter your ID number"> </div> </div> <div > <div > <label for="email">Email <span style="color: red;">*</span></label> <input type="email" name="email" placeholder="Enter your email"> </div> <div > <label for="birthdate">Date of Birth <span style="color: red;">*</span></label> <input type="date" name="birthdate" max="2006-10-01" min="1924-01-01"> </div> </div> </section> <section > <div > <label for="document">Upload CV <span style="color: red;">*</span></label> <input type="file" name="document" > </div> <div > <label for="department">Department <span style="color: red;">*</span></label> <select name="department"> <option value="">Select a department</option> <option value="hr">Human Resources</option> <option value="it">Information Technology</option> <option value="finance">Finance</option> </select> </div> </section> <section > <div > <label for="skills">Skills (Optional)</label> <textarea name="skills" rows="4" placeholder="Enter your skills"></textarea> </div> <div > <input type="checkbox" name="terms" > <label for="terms">I agree to the terms and conditions <span style="color: red;">*</span></label> </div> <button type="submit">Confirm and Submit</button> </section> <div > <button type="button" >Previous</button> <span ></span> <button type="button" >Next</button> </div> </form> <script src="script.js"></script>
ここで、必要な各入力に何らかの値があるかどうか、電子メール入力に有効な入力があるかどうかを確認します。次に、それに応じてisValidブール波を設定します。また、ShowerRor()関数を呼び出しますが、これはまだ定義されていません。
このコードをbealteStep()関数の上に貼り付けます:
:root { --primary-color: #8c852a; --secondary-color: #858034; } body { font-family: sans-serif; line-height: 1.4; margin: 0 auto; padding: 20px; background-color: #f4f4f4; max-width: 600px; } h1 { text-align: center; } form { background: #fff; padding: 40px; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); display: flex; flex-direction: column; } .form-group { display: flex; gap: 7%; } .form-group > div { width: 100%; } input:not([type="checkbox"]), select, textarea { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; } .form-control { margin-bottom: 15px; } button { display: block; width: 100%; padding: 10px; color: white; background-color: var(--primary-color); border: none; border-radius: 4px; cursor: pointer; font-size: 16px; } button:hover { background-color: var(--secondary-color); } .group-two, .group-three { display: none; } .arrows { display: flex; justify-content: space-between align-items: center; margin-top: 10px; } #navLeft, #navRight { width: fit-content; } @media screen and (max-width: 600px) { .form-group { flex-direction: column; } }
const stepInfo = document.getElementById("stepInfo"); const navLeft = document.getElementById("navLeft"); const navRight = document.getElementById("navRight"); const form = document.getElementById("myForm"); const formSteps = ["one", "two", "three"]; let currentStep = 0; function updateStepVisibility() { formSteps.forEach((step) => { document.getElementById(step).style.display = "none"; }); document.getElementById(formSteps[currentStep]).style.display = "block"; stepInfo.textContent = `Step ${currentStep + 1} of ${formSteps.length}`; navLeft.style.display = currentStep === 0 ? "none" : "block"; navRight.style.display = currentStep === formSteps.length - 1 ? "none" : "block"; } document.addEventListener("DOMContentLoaded", () => { navLeft.style.display = "none"; updateStepVisibility(); navRight.addEventListener("click", () => { if (currentStep < formSteps.length - 1) { currentStep++; updateStepVisibility(); } }); navLeft.addEventListener("click", () => { if (currentStep > 0) { currentStep--; updateStepVisibility(); } }); });
最後に、ユーザーが正しい情報の入力を開始したときにエラーがなくなるように、リアルタイムエラー処理を追加する必要があります。この関数をvalimatestep()関数の下に追加します:
リアルタイム検証スクリプトを開きます
この関数は、入力を聴き、イベントを変更し、関数を呼び出してエラーをクリアすることで、入力が無効でない場合、エラーをクリアします。 Showerror()1の下にclearError()関数を貼り付けます:
formSteps.forEach((step) => { document.getElementById(step).style.display = "none"; });
そして、ユーザーが正しい値で入力するとエラーがクリアされました:
document.getElementById(formSteps[currentStep]).style.display = "block";`
フォームの提出
マルチステップ形式では、ユーザーが提出する前に最後にすべての回答の要約を表示し、必要に応じて回答を編集するオプションを提供することが価値があります。その人は、後方にナビゲートせずに以前の手順を見ることができないため、最後のステップで要約を表示すると、保証と間違いを修正する機会が与えられます。
マークアップに4番目のセクションを追加して、この要約ビューを保持し、その中の送信ボタンを移動しましょう。これをindex.html:
の3番目のセクションのすぐ下に貼り付けますHTMLを開きます
次に、javaScriptのフォームステップを更新して、
に読み取りますstepInfo.textContent = `Step ${currentStep + 1} of ${formSteps.length}`;
navLeft.style.display = currentStep === 0 ? "none" : "block"; navRight.style.display = currentStep === formSteps.length - 1 ? "none" : "block";
次に、この関数をscripts.js:
document.addEventListener("DOMContentLoaded", () => { navLeft.style.display = "none"; updateStepVisibility();
これにより、入力値がフォームの概要セクションに動的に挿入され、ファイル名が切り捨てられ、不要な入力のフォールバックテキストが提供されます。
次に、updatestepvisibility()関数を更新して、新しい関数を呼び出します。navRight.addEventListener("click", () => { if (currentStep < formSteps.length - 1) { currentStep++; updateStepVisibility(); } });
最後に、これをdomcontentloadedイベントリスナーに追加します:
<form > <section > <div > <div > <label for="name">Name <span style="color: red;">*</span></label> <input type="text" name="name" placeholder="Enter your name"> </div> <div > <label for="idNum">ID number <span style="color: red;">*</span></label> <input type="number" name="idNum" placeholder="Enter your ID number"> </div> </div> <div > <div > <label for="email">Email <span style="color: red;">*</span></label> <input type="email" name="email" placeholder="Enter your email"> </div> <div > <label for="birthdate">Date of Birth <span style="color: red;">*</span></label> <input type="date" name="birthdate" max="2006-10-01" min="1924-01-01"> </div> </div> </section> <section > <div > <label for="document">Upload CV <span style="color: red;">*</span></label> <input type="file" name="document" > </div> <div > <label for="department">Department <span style="color: red;">*</span></label> <select name="department"> <option value="">Select a department</option> <option value="hr">Human Resources</option> <option value="it">Information Technology</option> <option value="finance">Finance</option> </select> </div> </section> <section > <div > <label for="skills">Skills (Optional)</label> <textarea name="skills" rows="4" placeholder="Enter your skills"></textarea> </div> <div > <input type="checkbox" name="terms" > <label for="terms">I agree to the terms and conditions <span style="color: red;">*</span></label> </div> <button type="submit">Confirm and Submit</button> </section> <div > <button type="button" >Previous</button> <span ></span> <button type="button" >Next</button> </div> </form> <script src="script.js"></script>
マルチステップフォームを使用すると、ユーザーが送信する前に提供するすべての情報を編集して確認できるようになりました。
:root { --primary-color: #8c852a; --secondary-color: #858034; } body { font-family: sans-serif; line-height: 1.4; margin: 0 auto; padding: 20px; background-color: #f4f4f4; max-width: 600px; } h1 { text-align: center; } form { background: #fff; padding: 40px; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); display: flex; flex-direction: column; } .form-group { display: flex; gap: 7%; } .form-group > div { width: 100%; } input:not([type="checkbox"]), select, textarea { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; } .form-control { margin-bottom: 15px; } button { display: block; width: 100%; padding: 10px; color: white; background-color: var(--primary-color); border: none; border-radius: 4px; cursor: pointer; font-size: 16px; } button:hover { background-color: var(--secondary-color); } .group-two, .group-three { display: none; } .arrows { display: flex; justify-content: space-between align-items: center; margin-top: 10px; } #navLeft, #navRight { width: fit-content; } @media screen and (max-width: 600px) { .form-group { flex-direction: column; } }
マルチステップフォームをアクセス可能にすることは、基本から始まります:
セマンティックHTMLを使用します。これは戦いの半分です。適切なフォームラベルを使用して密接に続いています フォームをよりアクセスしやすいものにする他の方法には、小さな画面でクリックする必要がある要素に十分なスペースを与えることと、フォームナビゲーションと進行状況の指標に意味のある説明を与える必要があります。
ユーザーへのフィードバックを提供することは、その重要な部分です。一定の時間を経てユーザーのフィードバックを自動するのはあまりありませんが、ユーザーが自分でそれを却下できるようにすることは素晴らしいことではありません。コントラストとフォントの選択に注意を払うことも重要です。どちらもあなたのフォームがどれほど読みやすいかに影響を与えるためです。より技術的なアクセシビリティを得るために、マークアップに次の調整を行いましょう:
スキルを除くすべての入力にaria-required = "true"を追加します。
エラースパンにロール= "アラート"を追加します。
ロール= "status" aria-live = "polite" to g.stepinfo。
これは、スクリーン読者がステップ情報が状態のタブを保持することを理解するのに役立ちます。- そしてそれで、マルチステップフォームははるかにアクセスしやすいです。 結論
- ジョブアプリケーション用の4部構成のマルチステップフォームに行きます!この記事の一番上で言ったように、ジャグリングすることはたくさんあります。そのため、すぐに使えるソリューションを探してもあなたを責めることはありません。
しかし、マルチステップフォームをハンドロールする必要がある場合、それが死刑判決ではないことを願っています。良い、アクセス可能なプラクティスから背を向けることなく、ナビゲーションと検証を完了することで、あなたをそこに連れて行く幸せな道があります。
そしてこれが私がそれにアプローチした方法です!繰り返しますが、私はこれを個人的な挑戦として引き受け、どこまで手に入れることができるかを確認しました。しかし、これをユーザーエクスペリエンスとアクセシビリティの思いやりにさらに念頭に置くための追加の機会があるかどうかを知りたいです。
参照- Webフォームの構造(MDN)
- マルチページフォーム(w3c.org)
- アクセス可能なフォームを作成(A11yプロジェクト)
以上がバニラJavaScriptとCSSでマルチステップフォームを作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











先日、Corey Ginnivanのウェブサイトから、この特に素敵なビットを見つけました。そこでは、スクロール中にカードのコレクションが互いに積み重ねられていました。

Google Fontsが新しいデザイン(ツイート)を展開したようです。最後の大きな再設計と比較して、これははるかに反復的です。違いをほとんど伝えることができません

プロジェクトにカウントダウンタイマーが必要だったことはありますか?そのようなことのために、プラグインに手を伸ばすのは自然なことかもしれませんが、実際にはもっとたくさんあります

フレックスレイアウトの紫色のスラッシュ領域に関する質問フレックスレイアウトを使用すると、開発者ツールなどの混乱する現象に遭遇する可能性があります(D ...

要素の数が固定されていない場合、CSSを介して指定されたクラス名の最初の子要素を選択する方法。 HTML構造を処理するとき、あなたはしばしば異なる要素に遭遇します...

新しいプロジェクトの開始時に、SASSコンピレーションは瞬く間に起こります。これは、特にbrowsersyncとペアになっている場合は素晴らしい気分です。

フロントエンド開発でWindowsのような実装方法...
