HTML5 input 标签
HTML5 的 <input>
标签是表单中最常用的元素之一,它提供了丰富的类型和功能,用于收集用户的各种输入数据。本文将详细介绍 HTML5 中支持的 22 种 input 类型及其用法。
input 标签的基本结构
一个基本的 input 元素结构如下:
<input type="类型" name="字段名" value="默认值" />
其中 type
属性是最重要的属性,它决定了输入控件的类型和行为。HTML5 规范定义了 22 种不同的 type 值,每种类型都有其特定的用途和特性。
目录
- button:按钮
- checkbox:多选框
- color:颜色选择框
- date:日期选择框
- datetime-local:日期时间选择框
- email:邮箱输入框
- file:文件选择框
- hidden:隐藏
- image:图片按钮
- month:月份输入框
- number:数字输入框
- password:密码输入框
- radio:单选框
- range:滑块
- reset:重置按钮
- search:搜索输入框
- submit:提交按钮
- tel:电话号码输入框
- text:文本输入框
- time:时间选择框
- url:网址输入框
- week:周输入框
Input 类型快速参考
类型 | 用途 | 主要特点 | 浏览器支持 |
---|---|---|---|
button | 创建按钮 | 触发 JavaScript 操作 | 所有浏览器 |
checkbox | 多选框 | 可选择多个选项 | 所有浏览器 |
color | 颜色选择器 | 提供颜色选择界面 | 现代浏览器 |
date | 日期选择器 | 提供日期选择界面 | 现代浏览器 |
datetime-local | 日期时间选择器 | 提供日期和时间选择界面 | 有限支持 |
邮箱输入框 | 自动验证邮箱格式 | 现代浏览器 | |
file | 文件上传 | 允许用户选择文件 | 所有浏览器 |
hidden | 隐藏字段 | 不显示在页面上 | 所有浏览器 |
image | 图像按钮 | 使用图片作为提交按钮 | 所有浏览器 |
month | 月份选择器 | 选择年份和月份 | 有限支持 |
number | 数字输入框 | 只允许输入数字 | 现代浏览器 |
password | 密码输入框 | 隐藏输入内容 | 所有浏览器 |
radio | 单选框 | 只能选择一个选项 | 所有浏览器 |
range | 滑块 | 直观选择范围内的值 | 现代浏览器 |
reset | 重置按钮 | 重置表单内容 | 所有浏览器 |
search | 搜索输入框 | 优化的搜索体验 | 现代浏览器 |
submit | 提交按钮 | 提交表单数据 | 所有浏览器 |
tel | 电话输入框 | 优化电话号码输入 | 现代浏览器 |
text | 文本输入框 | 基本文本输入 | 所有浏览器 |
time | 时间选择器 | 提供时间选择界面 | 现代浏览器 |
url | 网址输入框 | 自动验证 URL 格式 | 现代浏览器 |
week | 周选择器 | 选择年份和周数 | 有限支持 |
button:按钮
<input type="button">
用于创建一个可点击的按钮,主要用于触发 JavaScript 事件处理程序。
基本用法
<input type="button" value="普通按钮" onclick="alert('按钮被点击了!')" />
常用属性
属性 | 描述 | 示例 |
---|---|---|
value | 设置按钮上显示的文本 | value="提交" |
onclick | 按钮被点击时执行的 JavaScript 代码 | onclick="myFunction()" |
disabled | 禁用按钮,使其不可点击 | disabled |
功能描述
<input type="button">
创建的按钮本身不会执行任何操作,需要通过 JavaScript 为其添加 onclick
事件处理程序来实现具体功能。
与 <button>
元素相比,<input type="button">
是一个自闭合标签,且只能包含纯文本内容,而 <button>
可以包含 HTML 内容,如图片或其他元素。
实用示例
表单数据校验
<form id="myForm">
<input type="text" id="username" placeholder="请输入用户名" />
<input type="button" value="提交" onclick="validateForm()" />
</form>
<script>
function validateForm() {
const username = document.getElementById("username").value;
if (username.trim() === "") {
alert("用户名不能为空!");
} else {
alert("验证通过,准备提交!");
// 这里可以添加表单提交逻辑
}
}
</script>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="button" | 1 | 12 | 1 | 15 | 1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="button" | 18 | 4 | 14 | 1 | 4.4 |
参考
checkbox:多选框
<input type="checkbox">
用于创建一个多选框,允许用户从一组选项中选择一个或多个选项。
基本用法
<div>
<input id="skill-html" name="skills" type="checkbox" value="html" checked />
<label for="skill-html">HTML</label>
</div>
<div>
<input id="skill-css" name="skills" value="css" type="checkbox" />
<label for="skill-css">CSS</label>
</div>
<div>
<input id="skill-js" name="skills" value="javascript" type="checkbox" />
<label for="skill-js">JavaScript</label>
</div>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义复选框的名称,用于表单提交时的标识 | name="skills" |
value | 复选框被选中时提交的值 | value="html" |
checked | 设置复选框默认选中 | checked |
disabled | 禁用复选框,使其不可选 | disabled |
功能描述
复选框允许用户从一组选项中选择零个、一个或多个选项。通常,具有相同 name
属性的复选框被视为一组相关选项。
当表单提交时,只有被选中的复选框的值才会被发送到服务器。如果没有选中任何复选框,那么这个 name
属性对应的表单数据将不会被提交。
实用示例
使用 JavaScript 获取选中的选项
<div>
<input id="fruit-apple" name="fruits" type="checkbox" value="apple" />
<label for="fruit-apple">苹果</label>
</div>
<div>
<input id="fruit-banana" name="fruits" type="checkbox" value="banana" />
<label for="fruit-banana">香蕉</label>
</div>
<div>
<input id="fruit-orange" name="fruits" type="checkbox" value="orange" />
<label for="fruit-orange">橙子</label>
</div>
<input type="button" value="获取选中的水果" onclick="getSelectedFruits()" />
<script>
function getSelectedFruits() {
const checkboxes = document.querySelectorAll(
'input[name="fruits"]:checked'
);
const selectedFruits = Array.from(checkboxes).map(
(checkbox) => checkbox.value
);
if (selectedFruits.length > 0) {
alert("你选择了:" + selectedFruits.join(", "));
} else {
alert("你没有选择任何水果");
}
}
</script>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="checkbox" | 1 | 12 | 1 | 15 | 1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="checkbox" | 18 | 4 | 14 | 1 | 4.4 |
参考
color:颜色选择框
<input type="color">
用于创建一个颜色选择器,让用户可以直观地选择颜色值。
基本用法
<label for="favcolor">选择颜色:</label>
<input type="color" id="favcolor" name="favcolor" value="#def0fd" />
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义输入框的名称,用于表单提交时的标识 | name="favcolor" |
value | 设置颜色选择器的默认颜色值 | value="#def0fd" |
required | 表示字段为必填项 | required |
disabled | 禁用颜色选择器,使其不可编辑 | disabled |
功能描述
颜色选择器允许用户通过图形界面选择颜色,也可以直接输入十六进制颜色值。当用户点击输入框时,浏览器会弹出一个颜色选择界面,用户可以通过拖动滑块或点击色板来选择颜色。
选择的颜色值会以十六进制格式(如 #def0fd
)存储在输入框的 value
属性中,并在表单提交时发送到服务器。
实用示例
实时颜色预览
<div>
<label for="bgcolor">背景颜色:</label>
<input type="color" id="bgcolor" name="bgcolor" value="#ffffff" />
</div>
<div
style="height: 200px; width: 100%; border: 1px solid #ccc; margin-top: 20px;"
id="preview-area"
>
<p>颜色预览区域</p>
</div>
<script>
function updateBackgroundColor() {
const color = document.getElementById("bgcolor").value;
document.getElementById("preview-area").style.backgroundColor = color;
}
// 添加事件监听器
document
.getElementById("bgcolor")
.addEventListener("input", updateBackgroundColor);
</script>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="color" | 20 | 14 | 29 | 12 | 12.1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="color" | 25 | 27 | 12 | 12.2 | 4.4 |
参考
date:日期选择框
<input type="date">
用于创建一个日期选择器,让用户可以方便地选择年、月、日。
基本用法
<label for="birthdate">出生日期:</label>
<input
type="date"
id="birthdate"
name="birthdate"
value="2023-07-05"
min="2023-01-01"
max="2023-12-31"
/>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义输入框的名称,用于表单提交时的标识 | name="birthdate" |
value | 设置日期选择器的默认日期值 | value="2023-12-25" |
min | 设置可选的最小日期 | min="1900-01-01" |
max | 设置可选的最大日期 | max="2024-12-31" |
required | 表示字段为必填项 | required |
disabled | 禁用日期选择器,使其不可编辑 | disabled |
功能描述
日期选择器提供了一个用户友好的界面,让用户可以通过日历视图选择日期,而不是手动输入。在移动设备上,通常会弹出系统级的日期选择器,提供更好的触摸体验。
选择的日期值会以 ISO 格式(YYYY-MM-DD,如 2023-12-25
)存储在输入框的 value
属性中,并在表单提交时发送到服务器。
通过设置 min
和 max
属性,可以限制用户可选择的日期范围,这对于需要收集特定时间范围内日期的场景非常有用。
实用示例
年龄验证
<div>
<label for="userbirthdate">您的出生日期:</label>
<input type="date" id="userbirthdate" name="userbirthdate" max="" required />
<span id="age-message"></span>
</div>
<script>
function calculateAge() {
const birthdate = document.getElementById("userbirthdate").value;
const messageElement = document.getElementById("age-message");
if (!birthdate) {
messageElement.textContent = "";
return;
}
const birthDateObj = new Date(birthdate);
const today = new Date();
let age = today.getFullYear() - birthDateObj.getFullYear();
const monthDiff = today.getMonth() - birthDateObj.getMonth();
// 如果今年还没过生日,年龄减1
if (
monthDiff < 0 ||
(monthDiff === 0 && today.getDate() < birthDateObj.getDate())
) {
age--;
}
if (age < 18) {
messageElement.textContent = "您未满18岁,部分功能可能受限";
messageElement.style.color = "red";
} else {
messageElement.textContent = `您今年${age}岁`;
messageElement.style.color = "green";
}
}
// 设置最大可选日期为今天
function setMaxDate() {
const today = new Date().toISOString().split("T")[0];
document.getElementById("userbirthdate").max = today;
}
// 初始化
setMaxDate();
// 添加事件监听器
document
.getElementById("userbirthdate")
.addEventListener("change", calculateAge);
</script>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="date" | 20 | 12 | 57 | 11 | 14.1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="date" | 25 | 57 | 11 | 5 | 4.4 |
参考
datetime-local:日期时间选择框
<input type="datetime-local">
用于创建一个日期时间选择器,让用户可以同时选择日期和时间(不包含时区信息)。
基本用法
<label for="appointment">预约时间:</label>
<input
type="datetime-local"
id="appointment"
name="appointment"
value="2023-07-05T13:55"
min="2023-01-01T00:00"
max="2023-12-31T23:59"
/>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义输入框的名称,用于表单提交时的标识 | name="appointment" |
value | 设置日期时间选择器的默认值 | value="2023-07-05T18:30" |
min | 设置可选的最小日期时间 | min="2023-01-01T00:00" |
max | 设置可选的最大日期时间 | max="2023-12-31T23:59" |
required | 表示字段为必填项 | required |
disabled | 禁用日期时间选择器,使其不可编辑 | disabled |
功能描述
注意
由于 datetime-local
类型受限于浏览器支持,并且不同浏览器在输入方法上存在差异,目前最好是使用第三方框架或库来展示,或者实现一个自己的输入控件。
另一个方法是拆分为 date
和 time
输入控件,这两个的支持都比 datetime-local
更广泛。
日期时间选择器允许用户同时选择日期和时间,时间精度通常为分钟。选择的值会以 ISO 格式(YYYY-MM-DDThh:mm,如 2023-07-05T18:30
)存储在输入框的 value
属性中。
通过设置 min
和 max
属性,可以限制用户可选择的日期时间范围,这对于预约系统等场景非常有用。
实用示例
预约时间选择器
<div>
<label for="booking-time">选择预约时间:</label>
<input
type="datetime-local"
id="booking-time"
name="booking-time"
min=""
required
/>
<span id="time-message"></span>
</div>
<script>
function checkBookingTime() {
const bookingTimeInput = document.getElementById("booking-time");
const bookingTime = bookingTimeInput.value;
const messageElement = document.getElementById("time-message");
if (!bookingTime) {
messageElement.textContent = "";
return;
}
const bookingDate = new Date(bookingTime);
const now = new Date();
// 检查是否至少提前30分钟预约
const minBookingTime = new Date(now.getTime() + 30 * 60000);
if (bookingDate < minBookingTime) {
messageElement.textContent = "请至少提前30分钟预约";
messageElement.style.color = "red";
} else {
messageElement.textContent = "预约时间可用";
messageElement.style.color = "green";
}
}
// 设置最小可选时间为当前时间加30分钟
function setMinBookingTime() {
const now = new Date();
const minBookingTime = new Date(now.getTime() + 30 * 60000);
// 格式化时间为YYYY-MM-DDThh:mm格式
const year = minBookingTime.getFullYear();
const month = String(minBookingTime.getMonth() + 1).padStart(2, "0");
const day = String(minBookingTime.getDate()).padStart(2, "0");
const hours = String(minBookingTime.getHours()).padStart(2, "0");
const minutes = String(minBookingTime.getMinutes()).padStart(2, "0");
document.getElementById(
"booking-time"
).min = `${year}-${month}-${day}T${hours}:${minutes}`;
}
// 初始化
setMinBookingTime();
// 添加事件监听器
document
.getElementById("booking-time")
.addEventListener("change", checkBookingTime);
</script>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="datetime-local" | 20 | 12 | 93 | 11 | 14.1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="datetime-local" | 25 | 93 | 11 | 5 | 4.4 |
参考
email:邮箱输入框
<input type="email">
用于创建一个邮箱地址输入框,它会自动验证输入内容是否符合标准的电子邮件格式。
基本用法
<label for="useremail">电子邮箱:</label>
<input
type="email"
id="useremail"
name="email"
placeholder="请输入您的邮箱地址"
required
/>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义输入框的名称,用于表单提交时的标识 | name="email" |
value | 设置邮箱输入框的默认值 | value="user@example.com" |
placeholder | 提示用户应该输入什么内容 | placeholder="请输入邮箱地址" |
required | 表示字段为必填项 | required |
disabled | 禁用邮箱输入框,使其不可编辑 | disabled |
maxlength | 限制输入的最大字符数 | maxlength="100" |
multiple | 允许输入多个邮箱地址,用逗号分隔 | multiple |
功能描述
邮箱输入框专门用于收集用户的电子邮件地址。当用户提交表单时,浏览器会自动验证输入内容是否符合标准的电子邮件格式(例如包含 @ 符号和域名等)。
如果输入的内容不符合电子邮件格式要求,浏览器会显示错误提示,要求用户修正输入内容。这种内置的验证功能可以帮助减少错误数据提交到服务器。
通过添加 multiple
属性,可以允许用户输入多个邮箱地址,每个地址之间用逗号分隔。
实用示例
实时邮箱验证
<div>
<label for="verification-email">电子邮箱:</label>
<input
type="email"
id="verification-email"
name="email"
placeholder="请输入您的邮箱地址"
required
/>
<span id="email-validation"></span>
</div>
<script>
function validateEmail() {
const emailInput = document.getElementById("verification-email");
const email = emailInput.value;
const validationElement = document.getElementById("email-validation");
if (!email) {
validationElement.textContent = "";
return;
}
// 简单的邮箱正则表达式验证
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (emailRegex.test(email)) {
validationElement.textContent = "邮箱格式正确";
validationElement.style.color = "green";
} else {
validationElement.textContent = "请输入正确的邮箱地址";
validationElement.style.color = "red";
}
}
// 添加事件监听器
document
.getElementById("verification-email")
.addEventListener("input", validateEmail);
</script>
可以使用
required
属性要求用户必须输入电子邮件地址可以使用
placeholder
属性在输入框中显示一个提示性的文本,引导用户输入正确的电子邮件格式可以使用
pattern
属性自定义校验规则邮箱必须是以 @163.com 为后缀 <input type="email" pattern=".+@163\.com" />
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="email" | 20 | 12 | 93 | 11 | 14.1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="email" | 25 | 93 | 11 | 5 | 4.4 |
参考
file:文件选择框
<input type="file">
用于创建一个文件上传控件,允许用户从本地计算机选择一个或多个文件进行上传。
基本用法
<label for="uploadfile">上传文件:</label>
<input type="file" id="uploadfile" name="file" accept="image/*,.pdf" />
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义输入框的名称,用于表单提交时的标识 | name="uploadfile" |
accept | 限制可选择的文件类型 | accept="image/*,.pdf" |
multiple | 允许选择多个文件 | multiple |
required | 表示字段为必填项 | required |
disabled | 禁用文件上传控件,使其不可用 | disabled |
功能描述
文件上传控件允许用户浏览和选择本地计算机上的文件。当用户点击控件时,浏览器会打开文件选择对话框,用户可以选择一个或多个文件。
通过 accept
属性可以限制用户只能选择特定类型的文件,这有助于提高用户体验并减少不必要的文件上传。例如,accept="image/*"
只允许上传图片文件。
添加 multiple
属性后,用户可以一次选择多个文件(在文件选择对话框中按住 Ctrl 或 Command 键进行多选)。
实用示例
图片预览和上传
<div>
<label for="profile-image">选择头像:</label>
<input
type="file"
id="profile-image"
name="profile-image"
accept="image/*"
required
/>
<div id="image-preview" style="margin-top: 10px; display: none;">
<img src="" alt="预览图" style="max-width: 200px; max-height: 200px;" />
</div>
</div>
<script>
function previewImage() {
const fileInput = document.getElementById("profile-image");
const previewContainer = document.getElementById("image-preview");
const previewImage = previewContainer.querySelector("img");
if (fileInput.files && fileInput.files[0]) {
const reader = new FileReader();
reader.onload = function (e) {
previewImage.src = e.target.result;
previewContainer.style.display = "block";
};
reader.readAsDataURL(fileInput.files[0]);
}
}
// 添加事件监听器
document
.getElementById("profile-image")
.addEventListener("change", previewImage);
</script>
文件类型说明
唯一文件类型说明符是一个字符串,每个唯一文件类型说明符可以采用下列形式之一:
- 一个以英文句号(“.”)开头的合法的不区分大小写的文件名扩展名。例如:
.jpg
、.pdf
或.doc
- 一个不带扩展名的 MIME 类型字符串
- 字符串
audio/*
,表示“任何音频文件” - 字符串
video/*
,表示“任何视频文件” - 字符串
image/*
,表示“任何图片文件”
accept
属性的值是包含一个或多个(用逗号分隔)唯一文件类型说明符的字符串
例如,一个文件选择器需要能被表示成一张图片的内容,包括标准的图片格式和 PDF 文件
<input type="file" accept="image/*,.pdf" />
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="file" | 1 | 12 | 1 | 11 | 1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="file" | 18 | 4 | 11 | 1 | 4.4 |
参考
hidden:隐藏
<input type="hidden">
用于在表单中创建一个隐藏的输入字段,它不会在页面上显示,但表单提交时其值会被发送到服务器。
基本用法
<input type="hidden" name="userid" value="123456" />
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义隐藏字段的名称,用于表单提交时的标识 | name="userid" |
value | 设置隐藏字段的值 | value="123456" |
功能描述
隐藏字段是一种特殊的表单元素,它不会在用户界面上显示,用户无法直接看到或编辑其内容。然而,当表单提交时,隐藏字段的值会与其他表单数据一起被发送到服务器。
隐藏字段通常用于:
- 存储页面状态信息
- 传递用户标识或会话标识
- 保存表单处理所需的配置参数
- 记录表单的来源或引用页面
实用示例
记录表单提交时间戳
<form action="submit-form.php" method="post">
<!-- 隐藏字段存储时间戳 -->
<input type="hidden" name="timestamp" id="form-timestamp" />
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required />
<button type="submit">提交</button>
</form>
<script>
// 在页面加载时设置时间戳
function setTimestamp() {
const timestampInput = document.getElementById("form-timestamp");
const now = new Date().getTime(); // 获取当前时间戳
timestampInput.value = now;
}
// 页面加载完成后设置时间戳
window.addEventListener("DOMContentLoaded", setTimestamp);
</script>
记录表单来源
<form action="process-order.php" method="post">
<!-- 隐藏字段存储来源页面 -->
<input type="hidden" name="source" value="product-page" />
<!-- 其他表单字段 -->
<label for="quantity">数量:</label>
<input type="number" id="quantity" name="quantity" min="1" value="1" />
<button type="submit">添加到购物车</button>
</form>
注意
尽管该值并未作为页面内容中显示给用户,但仍然可以使用任何浏览器的开发者工具或“查看源代码”功能来查看并进行编辑。请不要将表单的安全性依赖于使用 hidden
输入上
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="hidden" | 1 | 12 | 1 | 2 | 1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="hidden" | 18 | 4 | 11 | 1 | 4.4 |
参考
image:图片按钮
<input type="image">
用于创建一个图像作为表单提交按钮,用户可以通过点击图像来提交表单。
基本用法
<form>
<input
type="image"
id="submit-button"
name="submit"
src="image.png"
alt="提交按钮"
width="100"
height="50"
/>
</form>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义图像按钮的名称,用于表单提交时的标识 | name="submit-button" |
src | 指定要显示的图像路径或 URL | src="submit.png" |
alt | 为图像添加替代文本,提高可访问性 | alt="提交表单" |
width | 设置图像的宽度 | width="100" |
height | 设置图像的高度 | height="50" |
disabled | 禁用图像按钮,使其不可点击 | disabled |
功能描述
图像按钮是一种特殊的提交按钮,它用图像代替了默认的按钮外观。当用户点击图像按钮时,表单会被提交,同时还会将用户点击图像的坐标(相对于图像左上角的 x 和 y 坐标)发送到服务器。
坐标信息以 name.x
和 name.y
的形式发送,其中 name
是图像按钮的 name
属性值。例如,如果 name="submit"
,则会发送 submit.x=100&submit.y=50
。
图像按钮通常用于需要自定义按钮外观或实现图像映射等交互功能的场景。
实用示例
带确认对话框的图像提交按钮
<form id="confirm-form" action="submit-data.php" method="post">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required />
<input
type="image"
id="confirm-submit"
name="submit"
src="submit-button.png"
alt="确认提交"
width="120"
height="40"
/>
</form>
<script>
function confirmSubmit(event) {
// 阻止表单默认提交行为
event.preventDefault();
// 显示确认对话框
if (confirm("确定要提交表单吗?")) {
// 用户确认后,提交表单
document.getElementById("confirm-form").submit();
}
}
// 添加点击事件监听器
document
.getElementById("confirm-submit")
.addEventListener("click", confirmSubmit);
</script>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="image" | 1 | 12 | 1 | 15 | 1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="image" | 18 | 4 | 14 | 1 | 4.4 |
参考
month:月份输入框
<input type="month">
用于创建一个月份选择器,允许用户选择特定的年份和月份组合,值以 ISO 8601 格式(YYYY-MM)存储。
基本用法
<label for="birth-month">出生月份:</label>
<input
type="month"
id="birth-month"
name="birth-month"
min="1900-01"
max="2023-12"
value="2023-07"
/>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义输入框的名称,用于表单提交时的标识 | name="birth-month" |
value | 设置默认选中的月份,格式为 YYYY-MM | value="2023-07" |
min | 设置可选择的最小月份,格式为 YYYY-MM | min="1900-01" |
max | 设置可选择的最大月份,格式为 YYYY-MM | max="2023-12" |
required | 表示字段为必填项 | required |
disabled | 禁用输入框,使其不可编辑 | disabled |
功能描述
月份输入框提供了一个用户友好的界面,让用户可以轻松选择年份和月份,而不需要手动输入。在支持的浏览器中,它通常会显示一个下拉日历选择器。
值得注意的是,type="month"
的值始终以 ISO 8601 格式(YYYY-MM)提交,无论用户界面如何显示日期。
通过 min
和 max
属性,您可以限制用户只能选择特定范围内的月份,这对于需要收集出生日期、预订日期等场景非常有用。
实用示例
订阅月份选择器
<form id="subscription-form">
<label for="start-month">开始订阅月份:</label>
<input
type="month"
id="start-month"
name="start-month"
min="2023-09"
required
/>
<button type="submit">提交订阅</button>
</form>
<p id="confirmation"></p>
<script>
// 设置最小可选月份为当前月份
const today = new Date();
const currentMonth =
today.getFullYear() + "-" + String(today.getMonth() + 1).padStart(2, "0");
document.getElementById("start-month").min = currentMonth;
document
.getElementById("subscription-form")
.addEventListener("submit", function (event) {
event.preventDefault();
const startMonth = document.getElementById("start-month").value;
const confirmationMsg = document.getElementById("confirmation");
// 显示确认信息
confirmationMsg.textContent = `您已选择从 ${startMonth} 开始订阅。`;
confirmationMsg.style.color = "green";
});
</script>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="month" | 20 | 12 | No | 11 | No |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="month" | 25 | 18 | 14 | 1.5 | 4.4 |
参考
number:数字输入框
<input type="number">
用于创建一个数字输入框,专门用于输入数值,通常会显示上下箭头用于调整数值。
基本用法
<label for="quantity">数量:</label>
<input
type="number"
id="quantity"
name="quantity"
min="1"
max="10"
value="1"
step="1"
/>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义输入框的名称,用于表单提交时的标识 | name="quantity" |
value | 设置输入框的默认值 | value="1" |
min | 设置允许输入的最小值 | min="0" |
max | 设置允许输入的最大值 | max="100" |
step | 设置数值调整的步长 | step="0.5" |
required | 表示字段为必填项 | required |
readonly | 设置输入框为只读状态 | readonly |
disabled | 禁用输入框,使其不可编辑 | disabled |
功能描述
数字输入框用于收集用户的数值输入,可以限制输入范围,并提供上下箭头让用户调整数值。在移动设备上,点击数字输入框通常会弹出数字键盘。
注意
需要注意的是,虽然 type="number"
设计用于输入数字,但某些浏览器仍然允许用户输入非数字字符。为了确保数据有效性,建议在服务器端也进行数据验证。
实用示例
价格计算器
<div>
<label for="price">单价:</label>
<input
type="number"
id="price"
name="price"
min="0"
step="0.01"
value="10.99"
/>
</div>
<div>
<label for="count">数量:</label>
<input type="number" id="count" name="count" min="1" step="1" value="1" />
</div>
<div>
<p>总价:<span id="total">10.99</span> 元</p>
</div>
<script>
function calculateTotal() {
const price = parseFloat(document.getElementById("price").value);
const count = parseInt(document.getElementById("count").value);
const total = price * count;
document.getElementById("total").textContent = total.toFixed(2);
}
// 为两个输入框添加事件监听器
document.getElementById("price").addEventListener("input", calculateTotal);
document.getElementById("count").addEventListener("input", calculateTotal);
</script>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="number" | 7 | 12 | 29 | 15 | 5.1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="number" | 18 | 29 | 14 | 5 | 4.4 |
参考
password:密码输入框
<input type="password">
用于创建一个密码输入框,它会隐藏用户输入的字符,通常显示为星号(*)或圆点(•),用于保护敏感信息。
基本用法
<form>
<label for="user-password">密码:</label>
<input
type="password"
id="user-password"
name="password"
minlength="6"
placeholder="请输入密码"
required
/>
</form>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义输入框的名称,用于表单提交时的标识 | name="password" |
value | 设置输入框的默认值 | value="initial-value" |
placeholder | 显示在输入框中的提示文本 | placeholder="请输入密码" |
minlength | 设置密码的最小长度 | minlength="6" |
maxlength | 设置密码的最大长度 | maxlength="20" |
required | 表示字段为必填项 | required |
disabled | 禁用输入框,使其不可编辑 | disabled |
功能描述
密码输入框的主要目的是安全地收集用户的敏感认证信息。当用户输入文本时,浏览器会自动将输入的字符转换为不可读的符号,如星号(*)或圆点(•),防止他人从屏幕上看到密码内容。
需要注意的是,虽然密码输入框在客户端提供了基本的保护,但在实际应用中,还应该在服务器端对密码进行加密处理和安全存储,并且使用 HTTPS 协议进行传输,以防止中间人攻击。
实用示例
带密码可见性切换功能的密码输入框
<div class="password-container">
<label for="secure-password">密码:</label>
<div class="password-input-wrapper">
<input
type="password"
id="secure-password"
name="password"
minlength="8"
placeholder="请输入至少8位密码"
required
/>
<button type="button" id="toggle-password" aria-label="切换密码可见性">
👁️
</button>
</div>
<small>密码必须包含字母和数字</small>
</div>
<script>
const togglePassword = document.getElementById("toggle-password");
const passwordInput = document.getElementById("secure-password");
// 切换密码可见性
function togglePasswordVisibility() {
const type =
passwordInput.getAttribute("type") === "password" ? "text" : "password";
passwordInput.setAttribute("type", type);
// 更改按钮图标
togglePassword.textContent = type === "password" ? "👁️" : "👁️🗨️";
}
// 添加点击事件监听器
togglePassword.addEventListener("click", togglePasswordVisibility);
// 添加密码强度简单验证
passwordInput.addEventListener("input", function () {
const password = this.value;
const hasLetter = /[a-zA-Z]/.test(password);
const hasNumber = /\d/.test(password);
const feedbackText = this.nextElementSibling.nextElementSibling;
if (password.length > 0) {
if (hasLetter && hasNumber && password.length >= 8) {
feedbackText.textContent = "密码强度良好";
feedbackText.style.color = "green";
} else {
feedbackText.textContent = "密码必须包含字母和数字,且至少8位";
feedbackText.style.color = "red";
}
} else {
feedbackText.textContent = "密码必须包含字母和数字";
feedbackText.style.color = "inherit";
}
});
</script>
<style>
.password-input-wrapper {
position: relative;
display: inline-block;
}
#toggle-password {
position: absolute;
right: 5px;
top: 50%;
transform: translateY(-50%);
background: transparent;
border: none;
cursor: pointer;
font-size: 18px;
padding: 0 5px;
}
</style>
:::
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="password" | 1 | 12 | 1 | 2 | 1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="password" | 18 | 4 | 14 | 1 | 4.4 |
参考
radio:单选框
<input type="radio">
用于创建一个单选框,允许用户从一组互斥的选项中选择一个。
基本用法
<div>
<input id="gender-male" name="gender" type="radio" value="male" checked />
<label for="gender-male">男</label>
</div>
<div>
<input id="gender-female" name="gender" type="radio" value="female" />
<label for="gender-female">女</label>
</div>
<div>
<input id="gender-other" name="gender" type="radio" value="other" />
<label for="gender-other">其他</label>
</div>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义单选框组的名称,相同名称的单选框为一组 | name="gender" |
value | 单选框被选中时提交的值 | value="male" |
checked | 设置单选框默认选中 | checked |
disabled | 禁用单选框,使其不可选 | disabled |
功能描述
单选框用于从一组互斥的选项中选择一个。具有相同 name
属性的单选框被视为一组,在同一组中,只能有一个单选框被选中。
当用户选择一个单选框时,同组中的其他单选框会自动取消选中状态。
实用示例
使用 JavaScript 获取选中的值
<div>
<input id="payment-wechat" name="payment" type="radio" value="wechat" />
<label for="payment-wechat">微信支付</label>
</div>
<div>
<input id="payment-alipay" name="payment" type="radio" value="alipay" />
<label for="payment-alipay">支付宝</label>
</div>
<div>
<input id="payment-card" name="payment" type="radio" value="creditcard" />
<label for="payment-card">信用卡</label>
</div>
<input type="button" value="获取支付方式" onclick="getPaymentMethod()" />
<script>
function getPaymentMethod() {
const selectedPayment = document.querySelector(
'input[name="payment"]:checked'
);
if (selectedPayment) {
alert("你选择了:" + selectedPayment.value);
} else {
alert("请选择一种支付方式");
}
}
</script>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="radio" | 1 | 12 | 1 | 15 | 1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="radio" | 18 | 4 | 14 | 1 | 4.4 |
参考
range:滑块
基本用法
<label for="voice">声音:</label>
<input type="range" min="1" max="100" value="50" name="voice" id="voice" />
功能描述
<input type="range">
标签则是一种用于创造滑动条的标签,它可以让用户通过拖动滑块来选择一个指定范围内的数值
标签具有以下几个属性:
- name 属性:用于定义滑动条的名称,可以在提交表单时使用
- min 和 max 属性:分别定义滑动条可以选择的最小值和最大值
- value 属性:定义滑动条初始时的数值,默认为最小值
- step 属性:定义滑动条每次调整的步长,默认为 1
通过使用 <input type="range">
标签,开发人员可以为用户提供更直观、交互性更强的操作方式
它可以用于各种互动应用,比如调整音量、选择时长、拖动大小等
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="range" | 4 | 12 | 23 | 11 | 3.1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="range" | 57 | 52 | 11 | 5 | 4.4 |
参考
reset:重置按钮
<input type="reset">
用于创建一个重置按钮,当用户点击该按钮时,表单中的所有输入元素将恢复到它们的默认值。
基本用法
<form>
<label for="username">用户名:</label>
<input type="text" id="username" name="username" value="默认用户" />
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" placeholder="请输入邮箱" />
<div>
<input type="submit" value="提交" />
<input type="reset" value="重置" />
</div>
</form>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义重置按钮的名称 | name="reset-btn" |
value | 设置按钮上显示的文本 | value="清空表单" |
disabled | 禁用重置按钮,使其不可点击 | disabled |
功能描述
重置按钮会将表单中的所有输入元素恢复到它们的默认值(即页面加载时的值或通过 value
属性设置的初始值)。这个功能在用户需要重新填写表单时非常有用。
值得注意的是,重置按钮的行为是立即执行的,不会向用户显示确认对话框。因此,在使用时应谨慎考虑,特别是在包含大量输入字段的长表单中,用户可能会不小心点击重置按钮导致所有输入内容丢失。
实用示例
带确认对话框的重置按钮
<form id="user-profile-form">
<label for="fullname">姓名:</label>
<input type="text" id="fullname" name="fullname" value="张三" />
<label for="phone">电话:</label>
<input type="tel" id="phone" name="phone" placeholder="请输入电话号码" />
<label for="bio">个人简介:</label>
<textarea id="bio" name="bio" rows="3"></textarea>
<div>
<input type="submit" value="保存" />
<button type="button" id="confirm-reset">重置</button>
</div>
</form>
<script>
// 为自定义重置按钮添加点击事件监听器
const confirmResetBtn = document.getElementById("confirm-reset");
const userForm = document.getElementById("user-profile-form");
confirmResetBtn.addEventListener("click", function () {
// 显示确认对话框
if (confirm("确定要重置表单吗?所有未保存的更改将会丢失。")) {
// 用户确认后,重置表单
userForm.reset();
}
});
</script>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="reset" | 1 | 12 | 1 | 15 | 1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="reset" | 18 | 4 | 14 | 1 | 4.4 |
参考
search:搜索输入框
<input type="search">
用于创建一个专门的搜索输入框,它具有一些专为搜索功能设计的特性,如自动清除按钮和语义化标识。
基本用法
<form>
<label for="site-search">站内搜索:</label>
<input
type="search"
id="site-search"
name="q"
placeholder="请输入搜索关键词..."
autocomplete="off"
/>
<button type="submit">搜索</button>
</form>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义搜索输入框的名称,用于表单提交时的标识 | name="search-query" |
placeholder | 显示在输入框中的提示文本 | placeholder="搜索文章..." |
autocomplete | 控制浏览器自动完成功能 | autocomplete="off" |
minlength | 设置搜索关键词的最小长度 | minlength="2" |
maxlength | 设置搜索关键词的最大长度 | maxlength="50" |
required | 表示字段为必填项 | required |
disabled | 禁用输入框,使其不可编辑 | disabled |
功能描述
搜索输入框是专门为搜索功能设计的输入控件,与普通文本输入框相比,它具有以下特殊特性:
- 在支持的浏览器中,输入框右侧会显示一个清除按钮('x'图标),当用户输入内容后可一键清除
- 在移动设备上,点击搜索输入框通常会弹出优化的虚拟键盘,方便快速输入搜索内容
- 提供更好的语义化标识,帮助辅助技术识别这是一个搜索功能
需要注意的是,虽然 type="search"
提供了一些便利的功能,但在某些浏览器中,它也会应用一些默认样式,可能需要通过 CSS 来覆盖这些默认样式以符合您的设计需求。
实用示例
带实时搜索建议的搜索框
<div class="search-container">
<label for="realtime-search" class="sr-only">搜索:</label>
<input
type="search"
id="realtime-search"
name="search"
placeholder="搜索产品..."
minlength="2"
/>
<div id="search-suggestions" class="suggestions-dropdown"></div>
</div>
<script>
const searchInput = document.getElementById("realtime-search");
const suggestionsContainer = document.getElementById("search-suggestions");
let searchTimeout;
// 模拟搜索建议数据
const productData = [
"笔记本电脑",
"平板电脑",
"智能手机",
"无线耳机",
"智能手表",
"相机",
"充电器",
"数据线",
"保护壳",
"移动电源",
];
// 处理搜索输入
function handleSearchInput() {
const query = searchInput.value.toLowerCase().trim();
// 清除之前的超时
clearTimeout(searchTimeout);
if (query.length < 2) {
suggestionsContainer.style.display = "none";
return;
}
// 添加延迟以避免频繁请求
searchTimeout = setTimeout(() => {
// 过滤匹配的建议
const matchedSuggestions = productData.filter((product) =>
product.toLowerCase().includes(query)
);
// 显示或隐藏建议
if (matchedSuggestions.length > 0) {
displaySuggestions(matchedSuggestions);
} else {
suggestionsContainer.innerHTML =
'<div class="no-results">没有找到相关产品</div>';
suggestionsContainer.style.display = "block";
}
}, 300);
}
// 显示搜索建议
function displaySuggestions(suggestions) {
suggestionsContainer.innerHTML = "";
suggestions.forEach((suggestion) => {
const suggestionItem = document.createElement("div");
suggestionItem.className = "suggestion-item";
suggestionItem.textContent = suggestion;
// 添加点击事件
suggestionItem.addEventListener("click", () => {
searchInput.value = suggestion;
suggestionsContainer.style.display = "none";
// 这里可以添加执行搜索的代码
});
suggestionsContainer.appendChild(suggestionItem);
});
suggestionsContainer.style.display = "block";
}
// 监听输入事件
searchInput.addEventListener("input", handleSearchInput);
// 点击页面其他地方隐藏建议
document.addEventListener("click", (event) => {
if (!event.target.closest(".search-container")) {
suggestionsContainer.style.display = "none";
}
});
</script>
<style>
.search-container {
position: relative;
width: 300px;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.suggestions-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: white;
border: 1px solid #ddd;
border-top: none;
border-radius: 0 0 4px 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
max-height: 200px;
overflow-y: auto;
display: none;
z-index: 1000;
}
.suggestion-item {
padding: 10px 15px;
cursor: pointer;
border-bottom: 1px solid #f0f0f0;
}
.suggestion-item:hover {
background-color: #f5f5f5;
}
.suggestion-item:last-child {
border-bottom: none;
}
.no-results {
padding: 15px;
color: #666;
font-style: italic;
}
</style>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="search" | 5 | 12 | 4 | 10.6 | 5 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="search" | 18 | 4 | 14 | 4.2 | 4.4 |
参考
submit:提交按钮
<input type="submit">
用于创建一个表单提交按钮,当用户点击该按钮时,表单数据会被提交到表单的 action 属性指定的服务器端点。
基本用法
<form action="/submit-form" method="post">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required />
<br />
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required />
<br />
<input type="submit" id="submit-btn" name="submit-btn" value="提交表单" />
</form>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义提交按钮的名称,用于表单提交时的标识 | name="submit-form" |
value | 设置提交按钮显示的文本 | value="保存并提交" |
disabled | 禁用提交按钮,使其不可点击 | disabled |
form | 关联到指定的表单 ID,即使按钮不在表单内部 | form="user-form" |
formaction | 覆盖表单的 action 属性,指定表单提交的 URL | formaction="/special-submit" |
formmethod | 覆盖表单的 method 属性,指定提交方法(GET/POST) | formmethod="post" |
formenctype | 覆盖表单的 enctype 属性,指定表单数据的编码类型 | formenctype="multipart/form-data" |
功能描述
提交按钮是表单交互的核心组件,它的主要功能是触发表单数据的提交。当用户点击提交按钮时,浏览器会收集表单中的所有输入数据,并将其发送到服务器进行处理。
提交按钮与 <button type="submit">
标签的主要区别在于:
<input type="submit">
是自闭合标签,不支持包含子元素<button type="submit">
可以包含 HTML 内容,如图标、强调文本等,提供更丰富的视觉效果
使用 <input type="submit">
的优势在于:
- 简洁明了,适合基本的表单提交需求
- 具有良好的浏览器兼容性
- 可以使用 form 属性关联到不在同一表单元素内的表单
实用示例
带加载状态和表单验证的提交按钮
<form id="contact-form" action="/send-message" method="post">
<div>
<label for="contact-name">姓名:</label>
<input type="text" id="contact-name" name="name" required />
</div>
<div>
<label for="contact-email">邮箱:</label>
<input type="email" id="contact-email" name="email" required />
</div>
<div>
<label for="contact-message">留言:</label>
<textarea id="contact-message" name="message" rows="4" required></textarea>
</div>
<div>
<button type="submit" id="loading-submit" disabled="disabled">
<span id="submit-text">提交留言</span>
<span id="loading-indicator" style="display: none;">⏳ 提交中...</span>
</button>
</div>
<div id="submit-status" style="margin-top: 10px;"></div>
</form>
<script>
// 表单验证函数
function validateForm() {
const form = document.getElementById("contact-form");
const submitBtn = document.getElementById("loading-submit");
const submitText = document.getElementById("submit-text");
const loadingIndicator = document.getElementById("loading-indicator");
const statusMessage = document.getElementById("submit-status");
// 启用或禁用提交按钮
submitBtn.disabled = !form.checkValidity();
}
// 处理表单提交
function handleSubmit(event) {
event.preventDefault();
const form = document.getElementById("contact-form");
const submitBtn = document.getElementById("loading-submit");
const submitText = document.getElementById("submit-text");
const loadingIndicator = document.getElementById("loading-indicator");
const statusMessage = document.getElementById("submit-status");
// 显示加载状态
submitBtn.disabled = true;
submitText.style.display = "none";
loadingIndicator.style.display = "inline";
statusMessage.textContent = "";
// 模拟表单提交过程
setTimeout(() => {
// 恢复按钮状态
submitText.style.display = "inline";
loadingIndicator.style.display = "none";
// 显示提交成功消息
statusMessage.textContent = "留言已成功提交!";
statusMessage.style.color = "green";
// 重置表单
form.reset();
}, 2000);
}
// 添加事件监听器
const contactForm = document.getElementById("contact-form");
contactForm.addEventListener("input", validateForm);
contactForm.addEventListener("submit", handleSubmit);
// 初始化表单验证
validateForm();
</script>
<style>
#loading-submit {
padding: 10px 20px;
background-color: #4caf50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
#loading-submit:hover:not(:disabled) {
background-color: #45a049;
}
#loading-submit:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
</style>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="submit" | 1 | 12 | 1 | 15 | 1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="submit" | 18 | 4 | 14 | 1 | 4.4 |
参考
tel:电话号码输入框
<input type="tel">
用于创建一个专门的电话号码输入框,它能够在移动设备上触发数字键盘,并支持通过 pattern 属性进行基本的电话号码格式验证。
基本用法
<form>
<label for="phone-number">手机号码:</label>
<input
type="tel"
id="phone-number"
name="phone"
placeholder="请输入手机号码"
pattern="[0-9]{11}"
required
/>
<small>请输入11位数字的手机号码</small>
</form>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义电话号码输入框的名称,用于表单提交时的标识 | name="contact-phone" |
placeholder | 显示在输入框中的提示文本 | placeholder="010-12345678" |
pattern | 设置验证电话号码的正则表达式模式 | pattern="[0-9]{11}" |
required | 表示字段为必填项 | required |
maxlength | 设置允许输入的最大字符数 | maxlength="20" |
autocomplete | 控制浏览器自动完成功能 | autocomplete="tel" |
disabled | 禁用输入框,使其不可编辑 | disabled |
功能描述
电话号码输入框是专门为接收电话号码设计的表单控件,它具有以下特点:
- 在移动设备上,点击电话号码输入框会自动弹出数字键盘,提升用户输入体验
- 可以通过 pattern 属性配合正则表达式对输入的电话号码格式进行验证
- 支持 autocomplete 属性,当设置为 "tel" 时,浏览器可以提供电话号码自动填充功能
需要注意的是,仅依靠 HTML5 的 pattern 属性进行前端验证是不够的,在实际应用中,应该同时在服务器端进行电话号码格式的验证,以确保数据的准确性和安全性。
实用示例
带自动格式化和输入验证的电话号码输入框
<div class="phone-input-container">
<label for="formatted-phone">手机号码:</label>
<input
type="tel"
id="formatted-phone"
name="phone"
placeholder="请输入手机号码"
maxlength="13"
/>
<div id="phone-error" class="error-message"></div>
</div>
<script>
const phoneInput = document.getElementById("formatted-phone");
const errorMessage = document.getElementById("phone-error");
let lastValue = "";
// 格式化手机号码
function formatPhoneNumber(value) {
// 移除非数字字符
const cleanValue = value.replace(/\D/g, "");
// 格式化中国大陆手机号码(11位)
if (cleanValue.length <= 3) {
return cleanValue;
} else if (cleanValue.length <= 7) {
return `${cleanValue.slice(0, 3)}-${cleanValue.slice(3)}`;
} else if (cleanValue.length <= 11) {
return `${cleanValue.slice(0, 3)}-${cleanValue.slice(
3,
7
)}-${cleanValue.slice(7, 11)}`;
} else {
// 如果超过11位,返回前11位格式化后的结果
const first11Digits = cleanValue.slice(0, 11);
return `${first11Digits.slice(0, 3)}-${first11Digits.slice(
3,
7
)}-${first11Digits.slice(7)}`;
}
}
// 验证手机号码
function validatePhoneNumber(value) {
// 移除非数字字符
const cleanValue = value.replace(/\D/g, "");
// 中国大陆手机号码正则表达式(以1开头的11位数字)
const phonePattern = /^1\d{10}$/;
if (!cleanValue) {
errorMessage.textContent = "请输入手机号码";
errorMessage.style.display = "block";
return false;
}
if (!phonePattern.test(cleanValue)) {
errorMessage.textContent = "请输入有效的手机号码(11位数字)";
errorMessage.style.display = "block";
return false;
}
errorMessage.textContent = "";
errorMessage.style.display = "none";
return true;
}
// 输入事件处理
phoneInput.addEventListener("input", () => {
const currentValue = phoneInput.value;
// 检查是否是删除操作
const isDeleting = currentValue.length < lastValue.length;
if (!isDeleting) {
// 如果不是删除操作,则进行格式化
const formattedValue = formatPhoneNumber(currentValue);
phoneInput.value = formattedValue;
}
lastValue = phoneInput.value;
});
// 失去焦点时验证
phoneInput.addEventListener("blur", () => {
validatePhoneNumber(phoneInput.value);
});
// 表单提交前验证
// 如果这个输入框在表单中,可以在表单提交事件中添加验证
// form.addEventListener('submit', (e) => {
// if (!validatePhoneNumber(phoneInput.value)) {
// e.preventDefault();
// phoneInput.focus();
// }
// });
</script>
<style>
.phone-input-container {
position: relative;
max-width: 300px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input[type="tel"] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
box-sizing: border-box;
}
input[type="tel"]:focus {
outline: none;
border-color: #4caf50;
box-shadow: 0 0 5px rgba(76, 175, 80, 0.2);
}
.error-message {
color: #f44336;
font-size: 12px;
margin-top: 5px;
display: none;
}
input[type="tel"]:invalid + .error-message {
display: block;
}
</style>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="tel" | 3 | 12 | 1 | 11 | 4 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="tel" | 18 | 1 | 11 | 3 | 3.7 |
参考
text:文本输入框
<input type="text">
是最基本的输入类型,用于创建一个标准的单行文本输入框,允许用户输入任意文本内容。
基本用法
<label for="username">用户名:</label>
<input
type="text"
id="username"
name="username"
placeholder="请输入用户名"
minlength="4"
maxlength="18"
size="20"
required
/>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义输入框的名称,用于表单提交时的标识 | name="username" |
value | 设置输入框的默认值 | value="admin" |
placeholder | 输入框为空时显示的提示文本 | placeholder="请输入用户名" |
required | 表示字段为必填项 | required |
minlength | 设置输入文本的最小长度 | minlength="4" |
maxlength | 设置输入文本的最大长度 | maxlength="18" |
size | 设置输入框的显示宽度(字符数) | size="20" |
readonly | 设置输入框为只读状态 | readonly |
disabled | 禁用输入框,使其不可编辑 | disabled |
pattern | 使用正则表达式验证输入内容 | pattern="[A-Za-z0-9]+" |
功能描述
文本输入框是最常用的表单元素之一,用于收集用户的文本输入。它可以配置为接受各种类型的文本数据,并可以通过属性进行验证和限制。
实用示例
实时输入验证
<label for="phone">手机号:</label>
<input
type="text"
id="phone"
name="phone"
placeholder="请输入11位手机号码"
pattern="^1[3-9]\d{9}$"
maxlength="11"
oninput="validatePhone(this)"
/>
<span id="phone-error" style="color: red;"></span>
<script>
function validatePhone(input) {
const errorElement = document.getElementById("phone-error");
const phonePattern = /^1[3-9]\d{9}$/;
if (input.value.length > 0 && !phonePattern.test(input.value)) {
errorElement.textContent = "请输入正确的手机号码";
} else {
errorElement.textContent = "";
}
}
</script>
实时字数统计
<label for="comment">评论:</label>
<textarea
id="comment"
name="comment"
rows="4"
cols="50"
maxlength="200"
oninput="updateCounter(this)"
></textarea>
<p><span id="char-count">0</span>/200 字</p>
<script>
function updateCounter(textarea) {
const countElement = document.getElementById("char-count");
countElement.textContent = textarea.value.length;
}
</script>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="text" | 1 | 12 | 1 | 15 | 1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="text" | 18 | 4 | 14 | 1 | 4.4 |
参考
time:时间选择框
<input type="time">
用于创建一个时间选择输入框,允许用户以小时和分钟的格式选择特定时间点,支持 24 小时制和 12 小时制。
基本用法
<form>
<label for="appointment-time">预约时间:</label>
<input
type="time"
id="appointment-time"
name="appointment-time"
min="09:00"
max="18:00"
step="900"
required
/>
<small>营业时间:09:00 - 18:00(每15分钟一个时段)</small>
</form>
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义时间输入框的名称,用于表单提交时的标识 | name="meeting-time" |
value | 设置默认时间值(HH:MM 格式) | value="14:30" |
min | 设置可选的最小时间 | min="08:00" |
max | 设置可选的最大时间 | max="22:00" |
step | 设置时间间隔(秒),默认为 60 秒 | step="900" (15 分钟) |
required | 表示字段为必填项 | required |
disabled | 禁用输入框,使其不可编辑 | disabled |
autocomplete | 控制浏览器自动完成功能 | autocomplete="off" |
功能描述
时间选择输入框是专门为接收时间数据设计的表单控件,它具有以下特点:
- 在支持的浏览器中,会显示一个时间选择器,允许用户通过图形界面选择时间
- 在移动设备上,会弹出一个优化的时间选择界面,通常是时钟或滚轮式选择器
- 支持通过 min 和 max 属性限制可选择的时间范围
- 支持通过 step 属性设置可选的时间间隔
需要注意的是,时间选择器的外观和功能在不同浏览器中可能有所不同:
- 某些浏览器可能不支持图形化的时间选择器,而是显示为普通文本输入框
- 某些浏览器可能忽略 min、max 和 step 属性
- 提交的时间值通常采用 24 小时制的 ISO 8601 格式(HH:MM)
实用示例
带时间范围验证的预约时间选择器
<div class="appointment-form">
<h3>预约时间选择</h3>
<div class="form-group">
<label for="start-time">开始时间:</label>
<input
type="time"
id="start-time"
name="start-time"
min="09:00"
max="17:00"
step="300"
required
/>
</div>
<div class="form-group">
<label for="end-time">结束时间:</label>
<input type="time" id="end-time" name="end-time" required />
</div>
<div id="time-error" class="error-message"></div>
<button type="button" id="check-availability">检查可用性</button>
</div>
<script>
const startTimeInput = document.getElementById("start-time");
const endTimeInput = document.getElementById("end-time");
const errorMessage = document.getElementById("time-error");
const checkButton = document.getElementById("check-availability");
// 当开始时间改变时,更新结束时间的最小限制
startTimeInput.addEventListener("change", updateEndTimeMin);
// 当结束时间改变时,验证时间范围
endTimeInput.addEventListener("change", validateTimeRange);
// 检查可用性按钮点击事件
checkButton.addEventListener("click", () => {
if (validateTimeRange()) {
// 这里可以添加检查可用性的逻辑
errorMessage.textContent = "该时间段可用!";
errorMessage.className = "error-message success";
// 模拟API调用延迟
setTimeout(() => {
errorMessage.textContent = "";
errorMessage.className = "error-message";
}, 3000);
}
});
// 更新结束时间的最小限制
function updateEndTimeMin() {
if (startTimeInput.value) {
// 设置结束时间至少比开始时间晚30分钟
const startTime = new Date();
const [hours, minutes] = startTimeInput.value.split(":");
startTime.setHours(hours);
startTime.setMinutes(parseInt(minutes) + 30);
// 格式化最小结束时间
const minEndTime =
String(startTime.getHours()).padStart(2, "0") +
":" +
String(startTime.getMinutes()).padStart(2, "0");
endTimeInput.min = minEndTime;
// 如果当前结束时间小于新的最小时间,则清除它
if (endTimeInput.value && endTimeInput.value < minEndTime) {
endTimeInput.value = "";
}
}
}
// 验证时间范围
function validateTimeRange() {
if (!startTimeInput.value || !endTimeInput.value) {
errorMessage.textContent = "请选择开始时间和结束时间";
errorMessage.className = "error-message";
return false;
}
const start = new Date();
const end = new Date();
const [startHours, startMinutes] = startTimeInput.value.split(":");
const [endHours, endMinutes] = endTimeInput.value.split(":");
start.setHours(startHours);
start.setMinutes(startMinutes);
end.setHours(endHours);
end.setMinutes(endMinutes);
// 检查结束时间是否晚于开始时间
if (end <= start) {
errorMessage.textContent = "结束时间必须晚于开始时间";
errorMessage.className = "error-message";
return false;
}
// 检查时间范围是否超过2小时
const timeDiff = end - start;
const hoursDiff = timeDiff / (1000 * 60 * 60);
if (hoursDiff > 2) {
errorMessage.textContent = "预约时间范围不能超过2小时";
errorMessage.className = "error-message";
return false;
}
errorMessage.textContent = "";
return true;
}
</script>
<style>
.appointment-form {
max-width: 400px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
background-color: #f9f9f9;
}
.appointment-form h3 {
margin-top: 0;
color: #333;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #555;
}
input[type="time"] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
box-sizing: border-box;
}
input[type="time"]:focus {
outline: none;
border-color: #4caf50;
box-shadow: 0 0 5px rgba(76, 175, 80, 0.2);
}
.error-message {
color: #f44336;
font-size: 14px;
margin-top: 10px;
padding: 10px;
border-radius: 4px;
background-color: #ffebee;
}
.error-message.success {
color: #4caf50;
background-color: #e8f5e9;
}
button {
background-color: #2196f3;
color: white;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
width: 100%;
}
button:hover {
background-color: #0b7dda;
}
</style>
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="time" | 20 | 12 | 57 | 10 | 14.1 |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="time" | 25 | 57 | 10.1 | 5 | 4.4 |
参考
url:网址输入框
<input type="url">
是专门用于接收 URL 输入的表单控件,提供原生的 URL 格式验证功能,帮助确保用户输入符合标准的网址格式。
基本用法
<form>
<label for="website-url">网站地址:</label>
<input
type="url"
id="website-url"
name="website-url"
placeholder="https://example.com"
pattern="https://.*"
required
/>
</form>
常用属性
属性 | 描述 | 默认值 | 备注 |
---|---|---|---|
name | 控件的名称,用于表单提交时的标识 | - | 必须设置,用于服务器接收数据 |
id | 控件的唯一标识符,用于与 label 关联和 JavaScript 操作 | - | 建议设置,提高可访问性和可操作性 |
placeholder | 输入框为空时显示的提示文本 | - | 应提供有效的 URL 格式示例,如 https://example.com |
pattern | 用于验证输入值的正则表达式模式 | - | 可用于强制特定 URL 格式,如仅允许 HTTPS |
required | 表示输入框必须填写值 | false | 启用后,浏览器会在表单提交时验证输入框是否有值 |
disabled | 禁用输入框 | false | 禁用后输入框无法交互,且表单提交时不包含其值 |
readonly | 设置输入框为只读 | false | 只读时输入框内容不可修改,但表单提交时仍会包含其值 |
size | 输入框的显示宽度(以字符为单位) | 20 | 实际显示宽度可能因 CSS 样式而异 |
功能描述
<input type="url">
控件专门设计用于接收和验证 URL 输入,具有以下特性:
- 原生 URL 验证:浏览器会自动验证输入值是否符合 URL 格式规范,包括协议部分(如 http://、https://)、域名等
- 移动设备优化:在移动设备上,会弹出优化的键盘布局,方便用户输入 URL
- 自定义验证:通过
pattern
属性可以定义更严格的 URL 格式验证规则 - 表单验证集成:与 HTML5 表单验证 API 无缝集成,可以通过
required
属性设置为必填项
需要注意的是,浏览器验证仅检查 URL 的格式是否正确,不验证 URL 是否实际存在或可访问。对于需要验证 URL 有效性的场景,需要结合服务器端验证或 JavaScript 进行额外检查。
实用示例
带实时验证的网址输入框
下面是一个具有实时 URL 验证功能的完整示例,包括输入时的即时反馈和 URL 有效性检查:
<div class="url-validation-form">
<h3>网站URL验证</h3>
<div class="form-group">
<label for="url-input">输入网址:</label>
<input
type="url"
id="url-input"
name="url"
placeholder="https://example.com"
pattern="https://.*"
required
/>
<div id="url-feedback" class="feedback"></div>
</div>
<button type="button" id="validate-btn">验证URL</button>
<div id="validation-result" class="result"></div>
</div>
<script>
const urlInput = document.getElementById("url-input");
const urlFeedback = document.getElementById("url-feedback");
const validateBtn = document.getElementById("validate-btn");
const validationResult = document.getElementById("validation-result");
// 实时输入验证
urlInput.addEventListener("input", function () {
if (this.value) {
if (this.checkValidity()) {
urlFeedback.textContent = "URL格式正确";
urlFeedback.className = "feedback valid";
} else {
urlFeedback.textContent = "请输入有效的URL(以https://开头)";
urlFeedback.className = "feedback invalid";
}
} else {
urlFeedback.textContent = "";
urlFeedback.className = "feedback";
}
validationResult.textContent = "";
validationResult.className = "result";
});
// 点击验证按钮
validateBtn.addEventListener("click", function () {
if (!urlInput.checkValidity()) {
urlFeedback.textContent = "请输入有效的URL(以https://开头)";
urlFeedback.className = "feedback invalid";
return;
}
// 显示加载状态
this.disabled = true;
this.textContent = "验证中...";
validationResult.textContent = "正在检查URL有效性...";
validationResult.className = "result checking";
// 模拟URL有效性检查(实际项目中应使用AJAX请求)
setTimeout(() => {
const isValidUrl = simulateUrlCheck(urlInput.value);
if (isValidUrl) {
validationResult.textContent = "URL验证成功!这是一个有效的网址。";
validationResult.className = "result success";
} else {
validationResult.textContent =
"URL验证失败!无法访问该网址或该网址不存在。";
validationResult.className = "result error";
}
// 恢复按钮状态
this.disabled = false;
this.textContent = "验证URL";
}, 1500);
});
// 模拟URL检查函数
function simulateUrlCheck(url) {
// 这里仅做简单模拟,实际应用中应该使用fetch API或其他方式检查URL有效性
const validDomains = [
"example.com",
"github.com",
"google.com",
"microsoft.com",
];
try {
const urlObj = new URL(url);
return validDomains.some((domain) => urlObj.hostname.includes(domain));
} catch (e) {
return false;
}
}
</script>
<style>
.url-validation-form {
max-width: 500px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
background-color: #f9f9f9;
}
.url-validation-form h3 {
margin-top: 0;
color: #333;
font-size: 1.2em;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #555;
}
input[type="url"] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
box-sizing: border-box;
font-family: monospace;
}
input[type="url"]:focus {
outline: none;
border-color: #2196f3;
box-shadow: 0 0 5px rgba(33, 150, 243, 0.2);
}
.feedback {
margin-top: 5px;
font-size: 14px;
min-height: 20px;
}
.feedback.valid {
color: #4caf50;
}
.feedback.invalid {
color: #f44336;
}
button {
background-color: #2196f3;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover:not(:disabled) {
background-color: #0b7dda;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
.result {
margin-top: 15px;
padding: 10px;
border-radius: 4px;
min-height: 40px;
font-size: 14px;
}
.result.checking {
color: #2196f3;
background-color: #e3f2fd;
}
.result.success {
color: #4caf50;
background-color: #e8f5e9;
}
.result.error {
color: #f44336;
background-color: #ffebee;
}
</style>
参考
week:周输入框
<input type="week">
用于创建一个周选择器,允许用户选择特定的年份和周数组合,值以(YYYY-W##)格式存储。
基本用法
<label for="project-week">项目周:</label>
<input
type="week"
id="project-week"
name="project-week"
min="2023-W01"
max="2023-W52"
value="2023-W28"
/>
/* 基本用法的样式 */
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #555;
}
input[type="week"] {
width: 200px;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
input[type="week"]:focus {
outline: none;
border-color: #4caf50;
box-shadow: 0 0 5px rgba(76, 175, 80, 0.2);
}
// 基本用法的JavaScript(可选,此处为空)
常用属性
属性 | 描述 | 示例 |
---|---|---|
name | 定义输入框的名称,用于表单提交时的标识 | name="project-week" |
value | 设置默认选中的周,格式为 YYYY-W## | value="2023-W28" |
min | 设置可选择的最小周,格式为 YYYY-W## | min="2023-W01" |
max | 设置可选择的最大周,格式为 YYYY-W## | max="2023-W52" |
required | 表示字段为必填项 | required |
disabled | 禁用输入框,使其不可编辑 | disabled |
功能描述
周输入框提供了一个用户友好的界面,让用户可以轻松选择年份和周数,而不需要手动输入。在支持的浏览器中,它通常会显示一个下拉日历选择器。
值得注意的是,type="week"
的值始终以 ISO 8601 格式(YYYY-W##)提交,其中 W 后面跟两位数字表示周数(01-53),无论用户界面如何显示日期。
通过 min
和 max
属性,可以限制用户只能选择特定范围内的周。
实用示例
项目进度跟踪器
<div class="project-tracker">
<h3>项目进度跟踪</h3>
<form id="progress-form">
<div class="form-group">
<label for="start-week">开始周:</label>
<input
type="week"
id="start-week"
name="start-week"
min="2023-W01"
required
/>
</div>
<div class="form-group">
<label for="end-week">结束周:</label>
<input type="week" id="end-week" name="end-week" required />
</div>
<div class="form-group">
<label for="current-week">当前周:</label>
<input type="week" id="current-week" name="current-week" required />
</div>
<div id="progress-info" class="progress-info"></div>
<button type="button" id="calculate-progress">计算进度</button>
</form>
</div>
.project-tracker {
max-width: 500px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
background-color: #f9f9f9;
}
.project-tracker h3 {
margin-top: 0;
color: #333;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #555;
}
input[type="week"] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
box-sizing: border-box;
}
input[type="week"]:focus {
outline: none;
border-color: #4caf50;
box-shadow: 0 0 5px rgba(76, 175, 80, 0.2);
}
button {
background-color: #2196f3;
color: white;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
width: 100%;
}
button:hover {
background-color: #0b7dda;
}
.progress-info {
margin-top: 15px;
padding: 15px;
border-radius: 4px;
background-color: white;
}
.progress-details h4 {
margin-top: 0;
color: #333;
}
.progress-bar {
width: 100%;
height: 20px;
background-color: #e0e0e0;
border-radius: 10px;
overflow: hidden;
margin: 10px 0;
}
.progress-fill {
height: 100%;
background-color: #4caf50;
transition: width 0.3s ease;
}
.error {
color: #f44336;
background-color: #ffebee;
padding: 10px;
border-radius: 4px;
}
.info {
color: #2196f3;
background-color: #e3f2fd;
padding: 10px;
border-radius: 4px;
}
.success {
color: #4caf50;
background-color: #e8f5e9;
padding: 10px;
border-radius: 4px;
}
const startWeekInput = document.getElementById("start-week");
const endWeekInput = document.getElementById("end-week");
const currentWeekInput = document.getElementById("current-week");
const progressInfo = document.getElementById("progress-info");
const calculateBtn = document.getElementById("calculate-progress");
// 设置当前周为默认值
function setCurrentWeek() {
const now = new Date();
const year = now.getFullYear();
const weekNumber = getWeekNumber(now);
const currentWeekValue = `${year}-W${String(weekNumber).padStart(2, "0")}`;
currentWeekInput.value = currentWeekValue;
}
// 获取周数
function getWeekNumber(date) {
const firstDayOfYear = new Date(date.getFullYear(), 0, 1);
const pastDaysOfYear = (date - firstDayOfYear) / 86400000;
return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);
}
// 解析周值
function parseWeekValue(weekValue) {
const [year, week] = weekValue.split("-W");
return { year: parseInt(year), week: parseInt(week) };
}
// 计算周数差
function calculateWeekDifference(startWeek, endWeek) {
const start = parseWeekValue(startWeek);
const end = parseWeekValue(endWeek);
// 简化的周数差计算(实际应用中可能需要更复杂的逻辑)
const yearDiff = (end.year - start.year) * 52;
const weekDiff = end.week - start.week;
return yearDiff + weekDiff;
}
// 计算项目进度
function calculateProgress() {
const startWeek = startWeekInput.value;
const endWeek = endWeekInput.value;
const currentWeek = currentWeekInput.value;
if (!startWeek || !endWeek || !currentWeek) {
progressInfo.innerHTML = '<p class="error">请填写所有周数</p>';
return;
}
const totalWeeks = calculateWeekDifference(startWeek, endWeek);
const passedWeeks = calculateWeekDifference(startWeek, currentWeek);
if (totalWeeks <= 0) {
progressInfo.innerHTML = '<p class="error">结束周必须晚于开始周</p>';
return;
}
if (passedWeeks < 0) {
progressInfo.innerHTML = '<p class="info">项目尚未开始</p>';
return;
}
if (passedWeeks > totalWeeks) {
progressInfo.innerHTML = '<p class="success">项目已完成</p>';
return;
}
const progressPercentage = Math.round((passedWeeks / totalWeeks) * 100);
const remainingWeeks = totalWeeks - passedWeeks;
progressInfo.innerHTML = `
<div class="progress-details">
<h4>项目进度</h4>
<div class="progress-bar">
<div class="progress-fill" style="width: ${progressPercentage}%"></div>
</div>
<p>进度:${progressPercentage}%</p>
<p>已进行:${passedWeeks} 周</p>
<p>总时长:${totalWeeks} 周</p>
<p>剩余:${remainingWeeks} 周</p>
</div>
`;
}
// 当开始周改变时,更新结束周的最小限制
startWeekInput.addEventListener("change", function() {
if (this.value) {
endWeekInput.min = this.value;
if (endWeekInput.value && endWeekInput.value <= this.value) {
endWeekInput.value = "";
}
}
});
// 计算按钮点击事件
calculateBtn.addEventListener("click", calculateProgress);
// 初始化
setCurrentWeek();
浏览器兼容性
相关信息
数字表示该浏览器开始支持的版本
No 表示不支持
PC 端
PC 端 | Chrome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
type="week" | 20 | 12 | No | 11 | No |
移动端
移动端 | Chrome Android | Firefox Android | Opera Android | Safari IOS | WebView Android |
---|---|---|---|---|---|
type="week" | 25 | 18 | 14 | 1.5 | 4.4 |
参考
更新日志
38e56
-于8b50d
-于