多步骤形式是一个不错的选择。没有人愿意在移动设备上滚动浏览超长形式。通过按屏幕为基础对控件进行分组,我们可以改善填写长长的复杂形式的经验。
>但是您上次开发多步形式是什么时候?这对您来说听起来很有趣吗?有太多的思考,需要管理的许多动人的作品,以至于我不会怪您求助于表单库,甚至是某种为您处理所有这些形式的小部件。>
但是,手工做可以是一种很好的练习,也是抛光基础知识的好方法。我将向您展示如何构建我的第一个多步骤形式,希望您不仅可以看到它的接近程度,而且甚至可以发现使我的工作变得更好的领域。>
我们将一起浏览结构。我们将构建一个工作应用程序,我认为我们中的许多人都可以与最近几天有关。我将首先为基线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中文网其他相关文章!