表单是 Web 应用中收集用户输入的主要方式,JavaScript 提供了丰富的表单操作 API。
// 通过 ID 获取表单
const form = document.getElementById('myForm')
// 通过索引获取表单
const form = document.forms[0]
// 通过 name 属性获取表单
const form = document.forms['formName']
// 获取所有表单
const forms = document.forms
console.log(forms.length) // 表单数量const form = document.getElementById('myForm')
// 基本属性
console.log(form.action) // 提交 URL
console.log(form.method) // 提交方法 (GET/POST)
console.log(form.name) // 表单名称
console.log(form.target) // 目标窗口
// 表单状态
console.log(form.elements) // 所有表单控件
console.log(form.length) // 表单控件数量
console.log(form.acceptCharset) // 接受的字符集
console.log(form.enctype) // 编码类型// 通过索引获取
const field1 = form.elements[0]
// 通过 name 属性获取
const field2 = form.elements['fieldName']
// 通过 ID 获取(会自动添加到 elements 集合)
const field3 = form.elements['fieldId']const input = form.elements['username']
// 基本属性
console.log(input.type) // 字段类型
console.log(input.value) // 字段值
console.log(input.name) // 字段名称
console.log(input.form) // 所属表单
// 状态属性
console.log(input.disabled) // 是否禁用
console.log(input.readOnly) // 是否只读
console.log(input.tabIndex) // 制表符顺序
// 方法
input.focus() // 获取焦点
input.blur() // 失去焦点const textInput = document.getElementById('textInput')
// 获取和设置值
textInput.value = 'Default text'
console.log(textInput.value)
// 事件处理
textInput.addEventListener('focus', () => {
console.log('Input focused')
})
textInput.addEventListener('blur', () => {
console.log('Input blurred')
})
textInput.addEventListener('change', () => {
console.log('Value changed:', textInput.value)
})
textInput.addEventListener('input', () => {
console.log('Value changing:', textInput.value)
})
// 选择文本
textInput.select()
// 选择部分文本
textInput.setSelectionRange(0, 5)
// 获取选中文本
console.log(textInput.selectionStart, textInput.selectionEnd)const textarea = document.getElementById('textarea')
// 多行文本框特有属性
console.log(textarea.rows) // 行数
console.log(textarea.cols) // 列数
// 自动调整高度
function autoResize(textarea) {
textarea.style.height = 'auto'
textarea.style.height = textarea.scrollHeight + 'px'
}
textarea.addEventListener('input', () => autoResize(textarea))const select = document.getElementById('singleSelect')
// 获取选项
console.log(select.options) // HTMLOptionsCollection
console.log(select.length) // 选项数量
// 获取和设置选中值
console.log(select.value) // 选中选项的 value
console.log(select.selectedIndex) // 选中选项的索引
// 设置选中项
select.selectedIndex = 2
select.value = 'option3'
// 遍历选项
for (let option of select.options) {
console.log(option.value, option.text, option.selected)
}
// 添加选项
const newOption = new Option('New Option', 'newValue')
select.add(newOption)
// 移除选项
select.remove(1) // 移除索引为1的选项const multiSelect = document.getElementById('multiSelect')
// 获取所有选中值
function getSelectedValues(select) {
return Array.from(select.options)
.filter(option => option.selected)
.map(option => option.value)
}
console.log(getSelectedValues(multiSelect))
// 设置多选
multiSelect.options[0].selected = true
multiSelect.options[2].selected = true
// 全选/取消全选
function selectAll(select, selected) {
for (let option of select.options) {
option.selected = selected
}
}function serialize(form) {
const parts = []
const elements = form.elements
for (let element of elements) {
// 跳过没有 name 属性的字段
if (!element.name) continue
// 跳过禁用的字段
if (element.disabled) continue
// 跳过未选中的单选和复选框
if (element.type === 'radio' || element.type === 'checkbox') {
if (!element.checked) continue
}
// 跳过重置按钮和提交按钮
if (element.type === 'reset' || element.type === 'submit') continue
// 跳过文件字段
if (element.type === 'file') continue
parts.push(`${encodeURIComponent(element.name)}=${encodeURIComponent(element.value)}`)
}
return parts.join('&')
}
const serializedData = serialize(document.getElementById('myForm'))// 创建 FormData 对象
const formData = new FormData(document.getElementById('myForm'))
// 手动添加数据
formData.append('extraField', 'extraValue')
// 获取数据
for (let [key, value] of formData.entries()) {
console.log(key, value)
}
// 发送数据
fetch('/submit', {
method: 'POST',
body: formData
})<div id="editor" contenteditable="true">
<p>在这里编辑内容...</p>
</div>const editor = document.getElementById('editor')
// 获取和设置内容
console.log(editor.innerHTML)
editor.innerHTML = '<p>New content</p>'
// 监听输入
editor.addEventListener('input', () => {
console.log('Content changed:', editor.innerHTML)
})
// 基本格式化命令
function formatText(command, value = null) {
document.execCommand(command, false, value)
}
// 使用示例
document.getElementById('boldBtn').addEventListener('click', () => {
formatText('bold')
})
document.getElementById('italicBtn').addEventListener('click', () => {
formatText('italic')
})
document.getElementById('linkBtn').addEventListener('click', () => {
const url = prompt('Enter URL:')
if (url) formatText('createLink', url)
})<form id="validationForm">
<input type="email" name="email" required>
<input type="password" name="password" minlength="8">
<input type="number" name="age" min="18" max="120">
<input type="text" name="zip" pattern="[0-9]{5}">
<button type="submit">Submit</button>
</form>const form = document.getElementById('validationForm')
// 检查表单有效性
form.addEventListener('submit', (event) => {
if (!form.checkValidity()) {
event.preventDefault()
console.log('Form is invalid')
}
})
// 实时验证
const inputs = form.querySelectorAll('input')
inputs.forEach(input => {
input.addEventListener('input', () => {
if (input.validity.valid) {
input.classList.remove('invalid')
input.classList.add('valid')
} else {
input.classList.remove('valid')
input.classList.add('invalid')
}
})
})
// 自定义验证消息
const password = form.elements['password']
password.addEventListener('input', () => {
if (password.validity.tooShort) {
password.setCustomValidity('密码至少需要8个字符')
} else {
password.setCustomValidity('')
}
})function validateForm(form) {
const errors = []
// 自定义验证规则
const email = form.elements['email']
if (!isValidEmail(email.value)) {
errors.push('邮箱格式不正确')
}
const password = form.elements['password']
if (password.value.length < 8) {
errors.push('密码至少需要8个字符')
}
const confirmPassword = form.elements['confirmPassword']
if (password.value !== confirmPassword.value) {
errors.push('两次输入的密码不一致')
}
return errors
}
function isValidEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return regex.test(email)
}
// 使用自定义验证
form.addEventListener('submit', (event) => {
const errors = validateForm(form)
if (errors.length > 0) {
event.preventDefault()
displayErrors(errors)
}
})表单脚本是 Web 开发中的重要组成部分:
掌握表单脚本可以创建更好的用户交互体验。