多步驟形式是一個不錯的選擇。沒有人願意在移動設備上滾動瀏覽超長形式。通過按屏幕為基礎對控件進行分組,我們可以改善填寫長長的複雜形式的經驗。
>但是您上次開發多步形式是什麼時候?這對您來說聽起來很有趣嗎?有太多的思考,需要管理的許多動人的作品,以至於我不會怪您求助於表單庫,甚至是某種為您處理所有這些形式的小部件。>
但是,手工做可以是一種很好的練習,也是拋光基礎知識的好方法。我將向您展示如何構建我的第一個多步驟形式,希望您不僅可以看到它的接近程度,而且甚至可以發現使我的工作變得更好的領域。>
我們將一起瀏覽結構。我們將構建一個工作應用程序,我認為我們中的許多人都可以與最近幾天有關。我將首先為基線HTML,CSS和JavaScript腳手架,然後我們將研究以訪問性和驗證的考慮。>如果您想沿途參考,我已經為最終代碼創建了一個github存儲庫。
> 獲取示例代碼多步形式的結構
>導航用戶瀏覽各節意味著我們還將在剩下的步驟以及剩下多少個步驟中包含一個視覺指示器。該指示器可以是一個簡單的動態文本,該文本根據活動步驟或更高的進度條形類型的指示器進行更新。我們將做前者,以使事情變得簡單,並專注於形式的多步驟。
結構和基本樣式>我們將更多地關注邏輯,但是我將提供代碼片段和末尾的完整代碼的鏈接。
打開html
<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>
>打開瀏覽器中的HTML文件,您應該在以下屏幕截圖中獲得類似兩列佈局的內容,並使用當前頁面指示器和導航。
>使用香草JavaScript添加功能開放基本腳本
: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"; });
然後,我們獲取下一個按鈕,並添加單擊事件,該單擊事件有條件地增加當前步驟數,然後調用updateTepvisibility()函數,然後更新要顯示的新部分:
document.getElementById(formSteps[currentStep]).style.display = "block";`
處理錯誤
stepInfo.textContent = `Step ${currentStep + 1} of ${formSteps.length}`;
>您是否曾經花了10分鐘的時間來填寫表格,只是為了提交並遇到模糊錯誤告訴您要糾正這一點嗎?當表格立即告訴我有些不對勁時,我更喜歡它,以便我可以在
>之前糾正它。這就是我們將以我們的形式做的。navLeft.style.display = currentStep === 0 ? "none" : "block"; navRight.style.display = currentStep === formSteps.length - 1 ? "none" : "block";
>我們的原則是清楚地指出哪些控件有錯誤並提供有意義的錯誤消息。當用戶採取必要的操作時,明確錯誤。讓我們為我們的表格添加一些驗證。首先,讓我們抓住必要的輸入元素,然後將其添加到現有的輸入元素:
document.addEventListener("DOMContentLoaded", () => { navLeft.style.display = "none"; 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>
>在這裡,我們檢查每個必需的輸入是否具有一定的值,以及電子郵件輸入是否具有有效輸入。然後,我們相應地設置了Isvalid Boolean。我們還調用shower()函數,我們尚未定義。
>>粘貼此代碼上方的valialAteStep()函數:
>: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(); } }); });
>如果您刷新表單,您將看到按鈕不會將您帶到下一部分,直到輸入被認為有效:
>最後,我們要添加實時錯誤處理,以便當用戶開始輸入正確的信息時,錯誤會消失。在valialAteStep()函數下方添加此功能:
formSteps.forEach((step) => { document.getElementById(step).style.display = "none"; });
>
document.getElementById(formSteps[currentStep]).style.display = "block";`
現在,多步形式可以優雅地處理錯誤。如果您確實決定將錯誤保留到表格結束之前,則至少將用戶跳回錯誤的表單控制並顯示了他們需要修復多少錯誤的指示。
>處理表單提交
>讓我們在標記中添加第四部分,以保留此摘要視圖並在其中移動提交按鈕。將此粘貼在index.html的第三部分下方:
打開html
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();
>這將輸入值動態插入表單的摘要部分,截斷文件名,並為輸入提供了後備文本。
navRight.addEventListener("click", () => { if (currentStep < formSteps.length - 1) { currentStep++; updateStepVisibility(); } });
最後,將其添加到domcontentloaded事件偵聽器: >運行表格,您應該看到摘要部分顯示所有輸入的值,並允許用戶在提交信息之前編輯任何內容: 現在,我們可以提交我們的表格: 我們的多步表格現在允許用戶在提交之前編輯並查看其提供的所有信息。 使多步式形式訪問以基礎知識為開始:使用語義html。 這是戰鬥的一半。緊隨其後的是使用適當的表單標籤。
>
向用戶提供反饋是其中的重要組成部分;在一定的時間後自動自動使用用戶反饋並不是很棒,但是允許用戶自己解散。注意對比和字體選擇也很重要,因為它們都會影響您的形式的可讀性。
>向所有輸入添加aria-required =“ true”。
>在這裡,我們通過編程添加和刪除以其錯誤跨度明確連接輸入的屬性,並表明其處於無效狀態。
>,多步驟形式更容易訪問。
這就是我接近它的方式!同樣,我將此作為個人挑戰,以了解我能走多遠,我對此非常滿意。但是,我很想知道您是否看到了其他機會,使這更加註意用戶體驗和體貼可訪問性。 這是我在撰寫本文時提到的一些相關鏈接:<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;
}
}
>可訪問性提示
>添加角色=“警報”到錯誤跨度。
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";
});
參考
>如何構建Web表單(MDN)
以上是如何使用香草JavaScript和CSS創建多步驟形式的詳細內容。更多資訊請關注PHP中文網其他相關文章!