使用<fieldset>标签,为表单添加边框

博客提到标签是在其边框线中嵌入一个标题,并表示有实现效果的图示。
<div>
<div style="width: 600px">
<form>
    <fieldset>
        <legend>健康信息</legend>
        身高:<input type="text" />
        体重:<input type="text" />
    </fieldset>
</form>
</div>

其中标签是在其边框线中嵌入一个标题,实现的效果如下图:
标题嵌入在表单边框里

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>个人简历信息填写页面</title> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="container"> <h1>个人简历信息填写</h1> <form id="resumeForm" action="#" method="POST"> <!-- 个人信息部分 --> <fieldset> <legend>个人信息</legend> <label for="name">姓名:</label> <input type="text" id="name" name="name" required><br> <label for="email">邮箱:</label> <input type="email" id="email" name="email" required><br> <label for="phone">电话号码:</label> <input type="tel" id="phone" name="phone" pattern="[0-9]{11}" required><br> </fieldset> <!-- 教育背景部分 --> <fieldset> <legend>教育背景</legend> <label for="school">学校名称:</label> <input type="text" id="school" name="school" required><br> <label for="major">专业:</label> <input type="text" id="major" name="major" required><br> <label for="degree">学历:</label> <select id="degree" name="degree" required> <option value="本科">本科</option> <option value="硕士">硕士</option> <option value="博士">博士</option> </select> </fieldset> <!-- 工作经验部分 --> <fieldset> <legend>工作经验</legend> <label for="company">公司名称:</label> <input type="text" id="company" name="company"><br> <label for="position">职位:</label> <input type="text" id="position" name="position"><br> <label for="description">工作描述:</label> <textarea id="description" name="description" rows="4" cols="50"></textarea><br> </fieldset> <!-- 技能部分 --> <fieldset> <legend>技能</legend> <div id="skillsContainer"> <label for="skill">技能:</label> <input type="text" id="skill" name="skill[]"><br> </div> <button type="button" id="addSkill">添加技能</button><br> </fieldset> <!-- 提交按钮 --> <button type="submit">提交简历</button> </form> </div> <script src="scripts.js"></script> </body> </html>
最新发布
12-07
<think>我们有一个HTML表单,现在需要实现两个功能: 1. 在技能部分,点击“添加技能”按钮时,可以动态添加一个新的技能输入框。 2. 表单提交时,验证表单数据(例如,必填项不能为空,邮箱格式、电话格式正确等),验证通过则弹出提示信息(例如,alert('提交成功!'))并阻止表单的默认提交行为(即不跳转到action指定的页面,因为这里action="#")。 另外,我们还需要考虑: - 在动态添加技能输入框时,每个新的输入框应该有一个删除按钮,以便删除该技能项(但至少保留一个)。 - 表单验证:对每个必填项进行非空验证,邮箱格式验证,电话格式(11位数字)验证。 我们将使用纯JavaScript来实现这些功能。 步骤: 1. 添加技能输入框的功能: - 给“添加技能”按钮添加点击事件。 - 每次点击时,创建一个新的输入框(以及一个删除按钮),并添加到技能容器中。 - 删除按钮功能:点击删除按钮时,删除该行(注意:如果只有一个技能输入框,则删除按钮不可用或至少保留一个?题目要求至少保留一个,所以当只有一个时,删除按钮可以隐藏或者不添加删除功能?我们选择:当技能输入框多于一个时,每个都有删除按钮,点击删除按钮删除该输入框和按钮本身。) 2. 表单提交验证: - 监听表单的submit事件。 - 在事件处理函数中,获取各个输入字段的值,进行验证。 - 验证规则: - 姓名:非空 - 邮箱:非空且符合邮箱格式(简单的正则表达式检查) - 电话:非空且必须为11位数字(我们已经设置了pattern="[0-9]{11}",但为了确保,也可以在JS中再验证一次) - 学校、专业、学历:非空 - 工作经验部分不是必填项,可以不验证 - 技能:至少有一项技能(因为初始就有一个输入框,但用户可能没有填写,所以我们需要检查至少有一个技能输入框有内容?但是题目没有明确,我们可以设计为技能至少填写一项。或者根据需求,如果非必填,则可以不验证。根据题目,表单中只有个人信息和教育背景是必填的,工作经验不是必填,而技能部分初始有一个输入框且没有标记required,但通常简历技能是重要的,这里我们按照题目要求:题目中只有个人信息和教育背景的字段标记了required,所以技能不是必填。但是,题目要求“必填项不能为空”,所以技能部分不是必填,可以不验证。不过,为了完整性,我们可以考虑:至少有一个技能输入框(但允许为空)?或者要求至少填写一个技能?由于题目没有明确,我们按照一般理解:技能部分可以没有(即初始的输入框也可以为空)。所以,我们只验证必填项。 - 如果验证失败,显示错误信息(alert或者更友好的方式),并阻止表单提交。 - 如果验证通过,弹出成功提示,并阻止表单默认提交(因为我们只是前端模拟提交成功,实际提交可能需要通过AJAX,但题目没有要求,所以我们只alert)。 实现: 我们先写技能部分的动态添加和删除功能,然后写表单验证。 注意:动态添加的元素需要使用事件委托来绑定删除事件,或者每次创建时绑定。 我们将编写scripts.js文件的内容。 代码结构: 1. 等待DOM加载完成。 2. 获取“添加技能”按钮,并绑定点击事件。 3. 为删除按钮写一个处理函数(因为动态添加,所以可以在添加时绑定,也可以事件委托)。 4. 获取表单,并绑定submit事件。 详细代码: </think> 下面我将分析提供的HTML表单代码,并实现所需功能:动态添加技能输入框和表单提交验证。我会先展示完整的JavaScript解决方案,然后逐步解释代码。 ```html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>个人简历信息填写页面</title> <style> body { font-family: 'Microsoft YaHei', sans-serif; background-color: #f5f5f5; margin: 0; padding: 20px; color: #333; } .container { max-width: 800px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } h1 { color: #2c3e50; text-align: center; margin-bottom: 30px; } fieldset { border: 1px solid #ddd; border-radius: 5px; padding: 15px; margin-bottom: 20px; } legend { padding: 0 10px; font-weight: bold; color: #3498db; } label { display: block; margin: 10px 0 5px; font-weight: 600; } input, select, textarea { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; font-size: 16px; } textarea { resize: vertical; min-height: 100px; } button { background-color: #3498db; color: white; border: none; padding: 12px 20px; border-radius: 4px; cursor: pointer; font-size: 16px; margin-top: 10px; transition: background-color 0.3s; } button:hover { background-color: #2980b9; } #addSkill { background-color: #27ae60; } #addSkill:hover { background-color: #219653; } .skill-item { position: relative; margin-bottom: 10px; } .remove-skill { position: absolute; right: 0; top: 0; background: #e74c3c; color: white; border: none; border-radius: 50%; width: 24px; height: 24px; line-height: 24px; text-align: center; cursor: pointer; font-size: 14px; } .remove-skill:hover { background: #c0392b; } .error-message { color: #e74c3c; font-size: 14px; margin-top: 5px; display: none; } .error { border-color: #e74c3c; } </style> </head> <body> <div class="container"> <h1>个人简历信息填写</h1> <form id="resumeForm" action="#" method="POST"> <!-- 个人信息部分 --> <fieldset> <legend>个人信息</legend> <label for="name">姓名:</label> <input type="text" id="name" name="name" required> <div class="error-message" id="nameError">请输入姓名</div> <label for="email">邮箱:</label> <input type="email" id="email" name="email" required> <div class="error-message" id="emailError">请输入有效的邮箱地址</div> <label for="phone">电话号码:</label> <input type="tel" id="phone" name="phone" pattern="[0-9]{11}" required> <div class="error-message" id="phoneError">请输入11位手机号码</div> </fieldset> <!-- 教育背景部分 --> <fieldset> <legend>教育背景</legend> <label for="school">学校名称:</label> <input type="text" id="school" name="school" required> <div class="error-message" id="schoolError">请输入学校名称</div> <label for="major">专业:</label> <input type="text" id="major" name="major" required> <div class="error-message" id="majorError">请输入专业名称</div> <label for="degree">学历:</label> <select id="degree" name="degree" required> <option value="">--请选择学历--</option> <option value="本科">本科</option> <option value="硕士">硕士</option> <option value="博士">博士</option> </select> <div class="error-message" id="degreeError">请选择学历</div> </fieldset> <!-- 工作经验部分 --> <fieldset> <legend>工作经验</legend> <label for="company">公司名称:</label> <input type="text" id="company" name="company"> <label for="position">职位:</label> <input type="text" id="position" name="position"> <label for="description">工作描述:</label> <textarea id="description" name="description" rows="4" cols="50"></textarea> </fieldset> <!-- 技能部分 --> <fieldset> <legend>技能</legend> <div id="skillsContainer"> <div class="skill-item"> <input type="text" name="skill[]" class="skill-input" placeholder="例如:JavaScript"> <button type="button" class="remove-skill">×</button> </div> </div> <button type="button" id="addSkill">添加技能</button> </fieldset> <!-- 提交按钮 --> <button type="submit" id="submitBtn">提交简历</button> </form> </div> <script> document.addEventListener('DOMContentLoaded', function() { // 添加技能输入框 const addSkillBtn = document.getElementById('addSkill'); const skillsContainer = document.getElementById('skillsContainer'); addSkillBtn.addEventListener('click', function() { const skillItem = document.createElement('div'); skillItem.className = 'skill-item'; skillItem.innerHTML = ` <input type="text" name="skill[]" class="skill-input" placeholder="例如:Python"> <button type="button" class="remove-skill">×</button> `; skillsContainer.appendChild(skillItem); }); // 委托删除技能事件 skillsContainer.addEventListener('click', function(e) { if (e.target.classList.contains('remove-skill')) { // 确保至少保留一个技能输入框 if (document.querySelectorAll('.skill-item').length > 1) { e.target.closest('.skill-item').remove(); } else { alert('至少需要保留一项技能'); } } }); // 表单验证和提交处理 const form = document.getElementById('resumeForm'); form.addEventListener('submit', function(e) { e.preventDefault(); // 阻止默认提交行为 let isValid = true; // 清除之前的错误状态 document.querySelectorAll('.error-message').forEach(el => { el.style.display = 'none'; }); document.querySelectorAll('.error').forEach(el => { el.classList.remove('error'); }); // 验证必填字段 const requiredFields = [ { id: 'name', errorId: 'nameError' }, { id: 'email', errorId: 'emailError' }, { id: 'phone', errorId: 'phoneError' }, { id: 'school', errorId: 'schoolError' }, { id: 'major', errorId: 'majorError' }, { id: 'degree', errorId: 'degreeError' } ]; requiredFields.forEach(field => { const input = document.getElementById(field.id); const error = document.getElementById(field.errorId); if (!input.value.trim()) { isValid = false; input.classList.add('error'); error.style.display = 'block'; } }); // 邮箱格式验证 const emailInput = document.getElementById('email'); const emailError = document.getElementById('emailError'); const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (emailInput.value && !emailRegex.test(emailInput.value)) { isValid = false; emailInput.classList.add('error'); emailError.textContent = '邮箱格式不正确'; emailError.style.display = 'block'; } // 电话格式验证 const phoneInput = document.getElementById('phone'); const phoneError = document.getElementById('phoneError'); const phoneRegex = /^\d{11}$/; if (phoneInput.value && !phoneRegex.test(phoneInput.value)) { isValid = false; phoneInput.classList.add('error'); phoneError.style.display = 'block'; } // 技能非空验证 const skillInputs = document.querySelectorAll('.skill-input'); let hasSkill = false; skillInputs.forEach(input => { if (input.value.trim()) { hasSkill = true; } }); if (!hasSkill) { isValid = false; alert('请至少填写一项技能'); } // 表单提交处理 if (isValid) { // 实际项目中这里应该是AJAX提交 alert('简历提交成功!'); console.log('表单数据:', new FormData(form)); // form.reset(); // 可选:重置表单 } }); // 实时输入验证 document.querySelectorAll('input, select').forEach(input => { input.addEventListener('input', function() { if (this.classList.contains('error')) { this.classList.remove('error'); const errorId = this.id + 'Error'; const errorElement = document.getElementById(errorId); if (errorElement) { errorElement.style.display = 'none'; } } }); }); }); </script> </body> </html> ``` ### 代码功能解释: 1. **动态添加技能输入框**: - 点击"添加技能"按钮时创建新的技能输入项 - 每个输入项包含一个文本输入框和删除按钮 - 使用事件委托处理删除按钮点击事件 - 确保至少保留一个技能输入项 2. **表单验证功能**: - 阻止表单默认提交行为 - 验证所有必填字段(姓名、邮箱、电话、学校、专业、学历) - 验证邮箱格式(使用正则表达式) - 验证电话号码格式(11位数字) - 验证至少填写一项技能 - 实时清除错误状态(输入时移除错误样式) 3. **用户体验优化**: - 添加了错误提示信息 - 错误字段高亮显示(红色边框) - 表单提交成功提示 - 响应式设计适配不同设备 - 友好的用户交互反馈 4. **样式优化**: - 添加了完整的CSS样式 - 统一的配色方案和间距 - 交互元素(按钮)的悬停效果 - 错误信息的醒目显示 ### 实现要点说明: 1. **技能管理**: - 初始状态已有一个技能输入框 - 添加新技能项时使用模板字符串创建HTML元素 - 删除功能通过事件委托实现,避免单独绑定事件 2. **表单验证逻辑**: - 先清除所有之前的错误状态 - 逐项检查必填字段 - 使用正则表达式验证邮箱和电话格式 - 检查至少一项技能已填写 - 所有验证通过后显示成功提示 3. **用户体验增强**: - 错误信息显示在对应输入框下方 - 输入时自动清除错误状态 - 删除按钮有防误删保护(至少保留一项) - 表单元素获得焦点时有视觉反馈 此实现满足了需求中的所有功能点,并提供了良好的用户体验和错误处理机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值