1. 表单组件

<form>对应的是HTMLForm-Element类型,有它独有的属性和方法:

  • acceptCharset: 服务器能处理的字符集
  • action: 接受请求的URL
  • elements: 表单中所有控件的集合(HTMLCollectino)
  • enctype: 请求的编码类型
  • length: 表单中控件的数量
  • method: 要发送的HTTP请求类型,get/post
  • name: 表单的名称
  • reset(): 将所有表单域重置为默认值
  • submit(): 提交表单
  • target: 用于发送请求和接收响应的窗口名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<form method="post" action="/api">
<input type="text" size="25" maxlength="50" value="initial value" autofocus />
<textarea rows="25" cols="5"></textarea>
<input type="radio" name="color" value="red" readOnly />
<select name="location">
<option value="China">China</option>
</select>

<button type="submit">Submit Form</button>
<button type="reset">Reset Form</button>

<!-- HTML5约束验证API -->
<input type="text/email/url" name="username" required>
<input type="number" min="0" max="100" step="5" name="count">
<!--
input.stepUp(1);
input.stepDown(1);
-->
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 点击submit button时候,会自动调用submit方法
var form = document.getElementById("myForm");
EventUtil.addHandler(form, "submit", function(event){
// 阻止表单提交,先行验证表单数据
event = EventUtil.getEvent(event);
EventUtil.preventDefault(event);

// 表单字段的共有属性
var field = form.elements[0];
field.value = "Another value"; // 设置字段将被提交到服务器的值
field.disabled = true; // 禁用当前字段
field.type; // 字段的类型,如checkbox, radio
field.readOnly // 当前字段是否只读
field.focus(); // 把焦点设置到当前字段,实现自动切换焦点
field.blur(); // 失去焦点
field.select(); // 选中input, textarea的内容
form.submit();
})

// 点击reset button时候,会自动调用reset方法
EventUtil.addHandler(form, "reset", function(event){
event = EventUtil.getEvent(event);
EventUtil.preventDefault(event);

form.reset();
})

2. 文本框脚本

2.1 change事件

对于<input><textarea>,当它们获得焦点到失去焦点且value值改变时,才会触发change事件。对于<select>,只要用户选择了不同的选项,就会触发change事件。

1
2
3
4
var textbox = document.forms[0].elements[0];
EventUtil.addHandler(textbox, "change", function(event){
console.log(event.target.value)
})

2.2 select事件

使用select()可以选中文本。

1
2
3
4
var textbox = document.forms[0].elements[0];
textbox.select();
textbox.setSelectionRange(0, textbox.value.length); // "hello world"
textbox.setSeelctionRange(0, 3); // "hel"

同时当你在页面中选择文本时,会触发select事件。

1
2
3
EventUtil.addHandler(textbox, "select", function(event){
console.log('text selected' + textbox.value.substring(textbox.selectionStart, textbox.selectionEnd));
})

2.3 剪贴板事件

剪贴板事件
beforecopy 复制前触发
copy 复制时触发
beforecut 剪切前触发
cut 剪切时触发
beforepaste 粘贴前触发
paste 粘贴时触发

要访问剪贴板中的数据,可以使用clipboardData对象,这个对象有三个方法: getData(), setData(), clearData()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var EventUtil = {
// 获取剪贴板的文字
getClipboardText: function(event){
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData("text");
},
// 设置剪贴板的文字
setClipboardText: function(event, value){
if (event.clipboardData){
retrun event.clipboardData.setData("text/plain", value);
} else if (window.clipboardData){
return window.clipboardData.setData("text", value);
}
}
}

// 设置粘贴的内容
EventUtil.addHanler(textbox, "paste", function(event){
event = EventUtil.getEvent(event);
var text = EventUtil.getClipboardText(event);

// 确保只有数值才会被粘贴到文本框中
if (!/^\d*$/.test(text)){
event.preventDefault();
}
})

2.4 keypress事件过滤输入

响应文本框的keypress事件,阻止这个事件的默认行为来屏蔽此类字符。

1
2
3
4
5
6
EventUtil.addHandler(textbox, "keypress", function(event){
var charCode = EventUtil.getCharCode(event);
if (!/\d/.test(String.fromCharCode(charCode))){
event.preventDefault();
}
})

3. 选择框脚本

1
2
3
4
<!-- multiple 是否多选 -->
<select name="location" multiple>
<option value="1">China</option>
</select>

options包含了所有选项。每个options[i]都有index, label, selected, text, value属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var selectbox = document.forms[0].elements['location'];
selectbox.options[0].text; // 选线的文本
selectbox.options[0].value; // 选项的值

// 选中的选项 selectedIndex
var selectedIndex = selectbox.selectedIndex;
var selectedOption = selectbox.options[selectedIndex];

// 新增选项
var newOption = new Option("Option text", "Option value");
selectbox.add(newOption, undefined);

// 移除选项
seletbox.remove(0) // 移除第一个选项

4. 表单序列化与formData

浏览器怎样把表单数据发送给服务器:

  • 对表单字段的名称和值进行URL编码,使用(&)分隔。
  • 不发送禁用的表单字段,不发送type为reset, button, image的<button>和<input>
  • 只发送勾选的复选框和单选按钮,多选选择框中每个选中的值单独一个条目

XMLHttpRequest2为表单数据定义了formData类型,方便创建与表单格式相同的数据。

1
2
3
4
5
var data = new FormData();
data.append('name', 'Nicholas');

// 根据表单元素填入键值对
var data = new FormData(document.forms[0]);

创建了FormData的实例后,可以将它直接传给XHR的send()方法。使用FormData的方便之处体现在不必明确地在XHR对象上设置请求头部。XHR对象能够识别FormData的实例,并配置适当的头部信息。

1
2
3
4
5
6
var xhr = createXHR();
xhr.onreadystatechange = function(){
xhr.open('post', 'postexample.php', true);
var form = document.getElementById('user-info');
xhr.send(new FormData(form));
}

5. File API

5.1 File对象

2000年前,处理文件的唯一方式是在表单中加入<input type="file">字段。后来HTML5在DOM中为文件输入元素添加了一个files集合。选择了一个或多个文件时,files集合中将包含一组File对象,每个File对象都有下列只读属性:

  • name: 本地文件系统中的文件名
  • size: 文件的字节大小
  • type: 字符串,文件的MIME类型
  • lastModifiedDate: 字符串,文件上一次被修改的时间

通过监听change事件并读取files集合就可以知道选择的每个文件的信息

1
2
3
4
5
var fileList = document.getElementById('files-list');
EventUtil.addHanlder(fileList, "change", function(event){
var file = event.files[0];
console.log(file.name + file.type + file.size + 'bytes');
});

5.2 使用XHR上传文件

将文件拖进浏览器窗口,调用append()方法传入相应的file对象,再把FormData对象传递给XHR的send()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var droptarget = document.getElementById('droptarget');

function handleEvent(event){
event.preventDefault(event);

if (event.type == 'drop'){
var data = new FormData();
var files = event.dataTransfer.files;
for(var i = 0; i < files.length; i++){
data.append("file" + i, files[i]);
}

var xhr = new XMLHttpRequest();
xhr.open("post", "FileAPIExample06Upload.php", true);
xhr.send(data);
}
}

EventUtil.addHandler(droptarget, "dragenter", handleEvent);
EventUtil.addHandler(droptarget, "dragover", handleEvent);
EventUtil.addHandler(droptarget, "drag", handleEvent);

5.3 FileReader类型

FileReader是一种异步文件读取机制,FileReader提供了如下几个方法:

  • readAsText(file, encoding): 以纯文本形式读取文件,将读取到的文本保存在result属性中。
  • readAsDataURL(file): 读取文件并将文件以数据URI的形式保存在result属性中。
  • readAsBinaryString(file)
  • readAsArrayBuffer(file)

1. 了解form

1
2
3
4
5
6
7
8
9
10
<div>
<input v-model="postData.content" />
<button :disabled="postData.isSending" @click="send">发送</button>
<div>

<!-- ✅ 更优:用户可以通过回车键提交表单 -->
<div @submit.prevent="send">
<input v-model="postData.content" />
<button :disabled="postData.isSending">发送</button>
<div>

2. <form>

  • submit事件
    一定要使用 form 元素的submit事件。
    1
    2
    3
    4
    5
    <form>
    <input type="search" name="q">
    <button type="reset">重置</button>
    <button type="submit" hidden>搜索</button>
    </form>
1
2
3
4
5
6
7
8
9
form.addEventListener('submit', (event) => {
event.preventDefault()
const formData = new FormData(this)
fetch(this.action, {
method: this.method,
body: formData
})
form.reset()
})