当前位置: 首页 > news >正文

使用JS编写用户信息采集表单

使用JS编写一个好看的用户信息收集表单

实现效果

  • image-20250715233803822

实现代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>用户信息收集表单</title><style>body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;background-color: #f7f7f7;display: flex;justify-content: center;align-items: center;min-height: 100vh;margin: 0;padding: 20px;color: #333;}.form-container {background-color: white;border-radius: 8px;box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);width: 100%;max-width: 600px;padding: 30px;}h1 {color: #2c3e50;text-align: center;margin-bottom: 25px;font-weight: 500;}.form-group {margin-bottom: 20px;}label {display: block;margin-bottom: 8px;font-weight: 500;color: #2c3e50;}input[type="text"],input[type="number"] {width: 100%;padding: 12px;border: 1px solid #ddd;border-radius: 4px;font-size: 16px;transition: border-color 0.3s;}input:focus {outline: none;border-color: #3498db;box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);}.error-input {border-color: #e74c3c;}.error-input:focus {box-shadow: 0 0 0 2px rgba(231, 76, 60, 0.2);}.radio-group, .checkbox-group {display: flex;gap: 20px;margin-top: 8px;}.radio-group label, .checkbox-group label {display: flex;align-items: center;gap: 8px;font-weight: normal;cursor: pointer;}input[type="radio"], input[type="checkbox"] {width: 18px;height: 18px;cursor: pointer;}.error-message {color: #e74c3c;font-size: 14px;margin-top: 6px;display: none;}button {background-color: #3498db;color: white;border: none;border-radius: 4px;padding: 14px 25px;font-size: 16px;cursor: pointer;transition: background-color 0.3s;display: block;width: 100%;}button:hover {background-color: #2980b9;}.output-container {margin-top: 30px;}.output-box {margin-bottom: 15px;}textarea {width: 100%;height: 120px;padding: 12px;border: 1px solid #ddd;border-radius: 4px;font-family: inherit;resize: vertical;}textarea:focus {outline: none;border-color: #3498db;}</style>
</head>
<body><div class="form-container"><h1>用户信息收集</h1><form id="userForm"><div class="form-group"><label for="name">Name:</label><input type="text" id="name" name="name"><div class="error-message" id="nameError"></div></div><div class="form-group"><label for="age">Age:</label><input type="number" id="age" name="age" min="0"><div class="error-message" id="ageError"></div></div><div class="form-group"><label>Gender</label><div class="radio-group"><label><input type="radio" name="gender" value="male"> Male</label><label><input type="radio" name="gender" value="female"> Female</label></div><div class="error-message" id="genderError"></div></div><div class="form-group"><label for="phone">Phone:</label><input type="text" id="phone" name="phone"></div><div class="form-group"><label>Hobbies</label><div class="checkbox-group"><label><input type="checkbox" name="hobby" value="reading"> Reading</label><label><input type="checkbox" name="hobby" value="sports"> Sports</label><label><input type="checkbox" name="hobby" value="music"> Music</label></div></div><button type="button" id="submitBtn">Submit</button></form><div class="output-container"><div class="output-box"><label>Output:</label><textarea id="output" readonly></textarea></div><div class="output-box"><label>Errors:</label><textarea id="errors" readonly></textarea></div></div></div><script>document.getElementById('submitBtn').addEventListener('click', function() {// Clear previous errors and outputsdocument.getElementById('output').value = '';document.getElementById('errors').value = '';// Clear error messages and input stylingdocument.querySelectorAll('.error-message').forEach(el => {el.textContent = '';el.style.display = 'none';});document.querySelectorAll('input').forEach(input => {input.classList.remove('error-input');});// Collect form dataconst name = document.getElementById('name').value.trim();const age = document.getElementById('age').value;const gender = document.querySelector('input[name="gender"]:checked')?.value;const phone = document.getElementById('phone').value.trim();// Get selected hobbiesconst hobbies = Array.from(document.querySelectorAll('input[name="hobby"]:checked')).map(hobby => hobby.value);// Validate formlet isValid = true;const errorMessages = [];// Validate Nameif (!name) {showError('nameError', 'Name cannot be blank');isValid = false;} else if (name.length > 15) {showError('nameError', 'Name cannot exceed 15 letters');isValid = false;}// Validate Ageif (!age) {showError('ageError', 'Age cannot be blank');isValid = false;} else {const ageNum = Number(age);if (isNaN(ageNum)) {showError('ageError', 'Age must be a number');isValid = false;} else if (ageNum < 0) {showError('ageError', 'Age cannot be negative');isValid = false;}}// Validate Genderif (!gender) {showError('genderError', 'Please select a gender');isValid = false;}// Process form or display errorsif (isValid) {// Format the output dataconst output = [`Name: ${name}`,`Age: ${age}`,`Gender: ${gender.charAt(0).toUpperCase() + gender.slice(1)}`,`Phone: ${phone || 'Not provided'}`,`Hobbies: ${hobbies.length > 0 ? hobbies.join(', ') : 'None selected'}`].join('\n');document.getElementById('output').value = output;} else {document.getElementById('errors').value = errorMessages.join('\n');}});// Helper function to display validation errorsfunction showError(elementId, message) {const errorElement = document.getElementById(elementId);errorElement.textContent = message;errorElement.style.display = 'block';// Highlight error inputs based on error typeif (elementId === 'nameError') {document.getElementById('name').classList.add('error-input');} else if (elementId === 'ageError') {document.getElementById('age').classList.add('error-input');} else if (elementId === 'genderError') {document.querySelectorAll('input[name="gender"]').forEach(el => {el.closest('label').classList.add('error-input');});}// Add error message to listerrorMessages.push(message);}</script>
</body>
</html>

🖌️ 视觉篇:颜值即正义

/* 魔法起始!整个页面变成优雅的居中考场 */
body {display: flex;                /* 开启弹性布局魔法 */justify-content: center;       /* 左右居中 */align-items: center;           /* 垂直居中 */background-color: #f7f7f7;     /* 温柔的灰色背景 */
}/* 表单容器秒变精致卡片 */
.form-container {box-shadow: 0 4px 12px rgba(0,0,0,0.1);  /* 阴影:轻盈的漂浮感 */border-radius: 8px;            /* 圆角:拒绝尖锐伤害 */
}

设计亮点:

  • 输入框获得焦点时会出现蓝色光环 box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2),像被魔法棒点中一样✨
  • 错误输入框秒变"番茄色"警告:.error-input { border-color: #e74c3c }
  • 提交按钮悬停时颜色变深,仿佛在说:“摸我一下试试?” 👆

📝 结构篇:HTML的智慧组合

<!-- 分组管理就像文件柜 -->
<div class="form-group"><label for="name">Name:</label>    <!-- 贴心标签 --><input type="text" id="name">      <!-- 文本输入 --><div class="error-message"></div>  <!-- 预留错误展示位 -->
</div><!-- 单选组横向排列不打架 -->
<div class="radio-group"><label><input type="radio" name="gender" value="male"> Male</label><label><input type="radio" name="gender" value="female"> Female</label>
</div><!-- 兴趣爱好像个自助餐 -->
<div class="checkbox-group"><label><input type="checkbox" name="hobby" value="reading"> Reading</label><!-- 其他选项... -->
</div>

小心机设计:

  • name属性相同的radio自动成组(只能选一个)
  • 多选框name相同但允许多选,就像"我全都要!" 😏
  • 错误提示一开始是隐藏的 display: none,只在需要时跳出来

⚡ 互动篇:JavaScript的表演时刻

// 提交按钮:点我就开始表演!
submitBtn.addEventListener('click', () => {// 开场先清场打扫document.querySelectorAll('.error-message').forEach(el => {el.style.display = 'none';});// 开启侦探模式查案const name = nameInput.value.trim();if (!name) showError('nameError', '名字呢?你忘填啦!');else if (name.length > 15) showError('nameError', '名字太长记不住啦!');const age = ageInput.value;if (!age) showError('ageError', '年龄可是必考题!');else if (age < 0) showError('ageError', '咋的?来自未来?');
});

验证逻辑三巨头:

  1. 姓名:不能为空且≤15字符(超过时提示:“名字太长记不住啦!”)
  2. 年龄:必须为≥0的数字(负值会吐槽:“咋的?来自未来?”)
  3. 性别:必须选择(否则警告:“漏掉性别了亲!”)

成功后:

  • <textarea>里美美展示用户信息
  • 空手机号显示"Not provided",而不是尴尬的空白
  • 爱好自动拼接:hobbies.join(', ') → “Reading, Music”

💡 用户体验的闪光点

  • 实时反馈:错误输入框秒变红色+文字提示(像有个小助手在耳边提醒)
  • 包容设计:电话和爱好是可选项(用户:“终于不用编手机号了!”)
  • 错误分屏展示:成功时只显示结果,失败时单独列出错误日志
  • 性别单选组:排排站的设计比下拉菜单更直观

🚀 精妙代码技巧

// 1. 优雅获取单选值
const gender = document.querySelector('input[name="gender"]:checked')?.value;// 2. 获取多个复选框的黑科技
const hobbies = [...document.querySelectorAll('input[name="hobby"]:checked')].map(hobby => hobby.value);// 3. 错误处理函数(复用大师)
function showError(elementId, message) {const el = document.getElementById(elementId);el.textContent = message; el.style.display = 'block'; // 让错误信息闪亮登场
}

结语:这个表单会说话! 💬

这个表单最棒的地方在于:它懂用户更懂开发者

  • 用户看到的是优雅的卡片、聪明的提示和友好的反馈
  • 开发者看到的是清晰的代码结构、灵活的验证逻辑和易于维护的设计

下次做表单时,记得把这些小心思偷走哦!这可比干巴巴的<input>标签酷多啦~

http://www.lryc.cn/news/588660.html

相关文章:

  • 利用android studio,对图片资源进行二次压缩
  • 网络编程-epoll模型/udp通信
  • Node.js 中http 和 http/2 是两个不同模块对比
  • AutoGPT vs BabyAGI:自主任务执行框架对比与选型深度分析
  • python的形成性考核管理系统
  • 1.easypan-登录注册
  • P3842 [TJOI2007] 线段
  • 基于多智能体强化学习的医疗检索增强生成系统研究—MMOA-RAG架构设计与实现
  • 编程技能:多文件编译
  • c++图形题练习程序
  • LVS三种模式实战
  • 图机器学习(6)——图自编码器
  • 【电脑】显卡(GPU)的基础知识
  • 【轨物方案】当补贴退潮,光伏电站如何回归价值本质?
  • MySQL数据库----函数
  • 【PTA数据结构 | C语言版】二叉树前序序列化
  • 跨平台游戏引擎 Axmol-2.7.1 发布
  • git起步
  • 微信小程序翻书效果
  • 《汇编语言:基于X86处理器》第8章 高级过程(1)
  • 基于UDP/IP网络游戏加速高级拥塞控制算法(示意:一)
  • 力扣-使用双指针的方法的题们(持续更新中。。。
  • 一、CV_图像分类简介
  • Typecho插件开发:优化文章摘要处理短代码问题
  • 基于redis的分布式锁 lua脚本解决原子性
  • 银河麒麟服务器版挂载镜像文件
  • sqli-labs靶场通关笔记:第18-19关 HTTP头部注入
  • exe直接传输会导致文件损坏
  • 【html常见页面布局】
  • AI应用服务