背景
昨天表弟问了我一个问题
我立马会回了一段代码过去。岂能说不会!
分析
其实要快速获取表单数据的功能并不复杂。就两步
分析需求编写代码
- 要清楚常见的表单有哪些
- 根据表单获取到的数据结构是什么样子
常见的表单标签
email、date等存在兼容性的表单标签可以忽略。
文本框 input[type=text]
html
<input type="text">
密码框 input[type=password]
html
<input type="password">
文本域 textarea
html
<textarea></textarea>
下拉列表 select
html
<select></select>
单选框 input[type=radio]
html
<input type="radio">
复选框 input[type=checkbox]
html
<input type="checkbox">
文件选择框 input[type=file]
html
<input type="file">
获取表单值的方式
不同的标签,有不同的获取它们值的方式
文本框和密码框和文本域
他们都是通过 value属性直接获取值
js
dom.value
下拉列表
下拉列表其实也可以多选的 multiple
html
<select name="city" multiple>
<option value="广州">广州</option>
<option value="东莞">东莞</option>
<option value="佛山">佛山</option>
</select>
-
当下拉列表 没有添加多选时,直接 通过value属性即可获取到对应值。
dom.value
-
当下拉列表 添加多选时 ,获取获取子元素
option
,通过判断是否selected
来获取选中的值。jsconst select = document.querySelector("select") for (let index = 0; index < select.children.length; index++) { const option = select.children[index]; if (option.select) { console.log(option.value); } }
单选框
单选框的特点是 同一组单选框都会有同一个name属性。并且选中的单选框的checked属性为true
html
<input type="radio" name="gender" value="男" checked> 男
<input type="radio" name="gender" value="女"> 女
因此便可以通过这个特点来获取选中的单选框。获取的方式有两种
js
document.querySelector("[name=gender]:checked").value
或者
javascript
const radios = document.querySelectorAll("[name=gender]")
for (let index = 0; index < radios.children.length; index++) {
const radio = radios.children[index];
if (radio.checked) {
console.log(radio.value);
break
}
}
复选框
复选框的用法和单选框类似,只不过复选框是可以拥有多个值
html
<input type="checkbox" name="hobby" value="唱"> 唱
<input type="checkbox" name="hobby" value="跳"> 跳
<input type="checkbox" name="hobby" value="rap"> rap
<input type="checkbox" name="hobby" value="打篮球"> 打篮球
它的获取方式也有两种,一种直接querySelectorAll
带上合适的选择器即可
javascript
document.querySelectorAll("[name=hobby]:checked").value
另外一种也是遍历
js
const checkboxs = document.querySelectorAll("[name=hobby]")
for (let index = 0; index < checkboxs.children.length; index++) {
const checkbox = checkboxs.children[index];
if (checkbox.checked) {
console.log(checkbox.value);
}
}
文件选择框
最后是文件选择框,文件选择框需要通过 dom.files来获取即可,当然,它也可以通过添加 multiple
属性来实现多选
html
<input type="file" name="avatar" multiple>
js
dom.files // 获取到选中的文件
期望得到的数据结构
当我们了解了常见的表单标签后,那么我们要假设期待得到的数据结构
提炼关键信息:
-
当表单是 文本框 、密码框 、文本域 、单选框 时,我们都可以直接通过
value属性
来获取数据,并且存放时,他们是字符串类型js{ 文本框:"用户名", 密码框:"密码", 性别:"男" }
-
当表单是下拉列表时,存放它的值需要分情况
-
单选的下拉列表 (没有
multiple
属性),是字符串类型js{ 城市:"广州" }
-
多选的下拉列表 (有
multiple
属性),是数组类型js{ 城市:["广州","东莞"] }
-
-
当表单是 多选框时,存放它的数据时,是数组类型
js{ 喜好:["唱","跳","rap"] }
-
当表单是 文件选择框时,存放它的数据,是数组(因为可能多选文件)
js{ 照片:[照片1,照片2] }
编码流程
完整代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>快速获取表单数据</title>
</head>
<body>
<form>
<!-- 输入姓名的文本框 -->
<div>
<input type="text" placeholder="请输入姓名" name="userName" />
</div>
<!-- 选择性别的单选按钮 -->
<div>
<input type="radio" name="gender" value="男" /> 男
<input type="radio" name="gender" value="女" /> 女
</div>
<!-- 选择是否在世的单选按钮 -->
<div>
<input type="radio" name="alive" value="还在" checked /> 还在
<input type="radio" name="alive" value="上天了" /> 上天了
</div>
<!-- 选择兴趣爱好的复选框 -->
<div>
<input type="checkbox" name="hobby" value="唱" /> 唱
<input type="checkbox" name="hobby" value="跳" /> 跳
<input type="checkbox" name="hobby" value="rap" /> rap
<input type="checkbox" name="hobby" value="打篮球" /> 打篮球
</div>
<!-- 选择城市的下拉框 -->
<div>
<select name="city" multiple>
<option value="广州">广州</option>
<option value="东莞">东莞</option>
<option value="佛山">佛山</option>
</select>
</div>
<!-- 输入个人简介的文本域 -->
<div>
<textarea name="intro"></textarea>
</div>
<!-- 上传头像的文件输入框 -->
<div>
上传头像
<input type="file" name="avatar" multiple />
</div>
<!-- 提交按钮 -->
<div>
<button>提交</button>
</div>
</form>
<script>
// 获取表单元素并存储在常量form中
const form = document.querySelector('form')
// 为表单添加提交事件监听器
form.addEventListener('submit', function (e) {
// 阻止默认的表单提交行为
e.preventDefault()
// 序列化表单数据,并存储在常量data中
const data = serialize(form)
console.log(data)
})
// 定义序列化函数,接收一个表单元素作为参数
function serialize(tempForm) {
// 创建一个空对象,用于存储序列化后的表单数据
const data = {}
// 获取表单中所有具有"name"属性的字段
const formFieldList = tempForm.querySelectorAll('[name]')
// 遍历所有表单字段
formFieldList.forEach((field) => {
// 检查字段的类型和标签名
if (
field.type === 'text' ||
field.type === 'password' ||
field.tagName === 'TEXTAREA'
) {
// 如果是文本输入框或文本域,则将其值存储在data对象中
data[field.name] = field.value
} else if (field.tagName === 'SELECT') {
// 如果是下拉框
if (field.multiple) {
// 如果是多选下拉框,使用reduce将选中的项的值存储在数组中
data[field.name] = [...field.children].reduce((a, b) => {
if (b.selected) {
a.push(b.value)
}
return a
}, [])
} else {
// 如果是单选下拉框,直接将选中的项的值存储在data对象中
data[field.name] = field.value
}
} else if (field.type === 'radio' && field.checked) {
// 如果是单选按钮且被选中,则将其值存储在data对象中
data[field.name] = field.value
} else if (field.type === 'checkbox' && field.checked) {
// 如果是复选框且被选中
if (!data[field.name]) {
// 如果该字段在data对象中不存在,创建一个数组存储值
data[field.name] = [field.value]
} else {
// 如果已存在,将值添加到数组中
data[field.name].push(field.value)
}
} else if (field.type === 'file') {
// 如果是文件上传字段
// 如果支持多文件上传,将文件对象数组存储在data对象中
data[field.name] = field.files
}
})
// 返回包含序列化后数据的对象
return data
}
</script>
</body>
</html>