JavaScript高级语法之Form

 

目录

1 FormData类型

2 文件上传

2.1 使用POST方法,将enctype属性设为application/x-www-form-urlencoded

2.2 使用POST方法,将enctype属性设为text/plain。

2.3 使用POST方法,将enctype属性设为multipart/form-data。

2.4 使用GET方法,enctype属性将被忽略。

2.5 append()

3 表单的验证

3.1 HTML 5表单验证

3.2 checkValidity方法,setCustomValidity方法,validity对象

4 在JavaScript中访问表单或表单域


1 FormData类型

FormData类型可以用于构造表单数据。

var formData = new FormData();

formData.append('username', '张三');
formData.append('email', 'zhangsan@example.com');
formData.append('birthDate', 1940);

var xhr = new XMLHttpRequest();
xhr.open("POST", "/register");
xhr.send(formData);

上面的代码构造了一个formData对象,然后使用send方法发送。它的效果与点击下面表单的submit按钮是一样的。

<form id='registration' name='registration' action='/register'>
    <input type='text' name='username' value='张三'>
    <input type='email' name='email' value='zhangsan@example.com'>
    <input type='number' name='birthDate' value='1940'>
    <input type='submit' onclick='return sendForm(this.form);'>
</form>

FormData也可以将现有表单构造生成。

var formElement = document.querySelector("form");
var request = new XMLHttpRequest();
request.open("POST", "submitform.php");
request.send(new FormData(formElement));

FormData对象还可以对现有表单添加数据,这为我们操作表单提供了极大的灵活性。

function sendForm(form) {
    var formData = new FormData(form);
    formData.append('csrf', 'e69a18d7db1286040586e6da1950128c');

    var xhr = new XMLHttpRequest();
    xhr.open('POST', form.action, true);
    xhr.onload = function(e) {
        // ...
    };
    xhr.send(formData);

    return false;
}

var form = document.querySelector('#registration');
sendForm(form);

FormData对象也能用来模拟File控件,进行文件上传。

function uploadFiles(url, files) {
  var formData = new FormData();

  for (var i = 0, file; file = files[i]; ++i) {
    formData.append(file.name, file); // 可加入第三个参数,表示文件名
  }

  var xhr = new XMLHttpRequest();
  xhr.open('POST', url, true);
  xhr.onload = function(e) { ... };

  xhr.send(formData);  // multipart/form-data
}

document.querySelector('input[type="file"]').addEventListener('change', function(e) {
  uploadFiles('/server', this.files);
}, false);

FormData也可以加入JavaScript生成的文件。

// 添加JavaScript生成的文件
var content = '<a id="a"><b id="b">hey!</b></a>';
var blob = new Blob([content], { type: "text/xml"});
formData.append("webmasterfile", blob);

2 文件上传

HTML网页的<form>元素能够以四种格式,向服务器发送数据。

2.1 使用POST方法,将enctype属性设为application/x-www-form-urlencoded

<form action="register.php" method="post" onsubmit="AJAXSubmit(this); return false;">
</form>

这种方法是默认方法,POST发送,Encoding type为application/x-www-form-urlencoded。

Content-Type: application/x-www-form-urlencoded

foo=bar&baz=The+first+line.&#37;0D%0AThe+second+line.%0D%0A

2.2 使用POST方法,将enctype属性设为text/plain

<form action="register.php" method="post" enctype="text/plain" onsubmit="AJAXSubmit(this); return false;">
</form>

这种方法是POST发送,Encoding type为text/plain。

Content-Type: text/plain

foo=bar
baz=The first line.
The second line.

2.3 使用POST方法,将enctype属性设为multipart/form-data

<form action="register.php" method="post" enctype="multipart/form-data" onsubmit="AJAXSubmit(this);
 return false;">
</form>

这种方法是POST发送,Encoding type为multipart/form-data。

Content-Type: multipart/form-data; boundary=---------------------------314911788813839

-----------------------------314911788813839
Content-Disposition: form-data; name="foo"

bar
-----------------------------314911788813839
Content-Disposition: form-data; name="baz"

The first line.
The second line.

-----------------------------314911788813839--

2.4 使用GET方法,enctype属性将被忽略

<form action="register.php" method="get" onsubmit="AJAXSubmit(this); return false;">
</form>

这种方法是GET请求。

?foo=bar&baz=The%20first%20line.%0AThe%20second%20line.

某个表单有两个字段,分别是foobaz,其中foo字段的值等于barbaz字段的值一个分为两行的字符串。上面四种方法,都可以将这个表单发送到服务器。

通常,我们使用file控件实现文件上传。

<form id="file-form" action="handler.php" method="POST">
  <input type="file" id="file-select" name="photos[]" multiple/>
  <button type="submit" id="upload-button">上传</button>
</form>

上面HTML代码中,file控件的multiple属性,指定可以一次选择多个文件;如果没有这个属性,则一次只能选择一个文件。

file对象的files属性,返回一个FileList对象,包含了用户选中的文件。

var fileSelect = document.getElementById('file-select');
var files = fileSelect.files;

然后,新建一个FormData对象的实例,用来模拟发送到服务器的表单数据,把选中的文件添加到这个对象上面。

var formData = new FormData();

for (var i = 0; i < files.length; i++) {
  var file = files[i];

  if (!file.type.match('image.*')) {
    continue;
  }

  formData.append('photos[]', file, file.name);
}

2.5 append()

上面代码中的FormData对象的append方法,除了可以添加文件,还可以添加二进制对象(Blob)或者字符串。

// Files
formData.append(name, file, filename);

// Blobs
formData.append(name, blob, filename);

// Strings
formData.append(name, value);

append方法的第一个参数是表单的控件名,第二个参数是实际的值,第三个参数是可选的,通常是文件名。

最后,使用Ajax方法向服务器上传文件。

var xhr = new XMLHttpRequest();

xhr.open('POST', 'handler.php', true);

xhr.onload = function () {
  if (xhr.status !== 200) {
    alert('An error occurred!');
  }
};

xhr.send(formData);

目前,各大浏览器(包括IE 10)都支持Ajax上传文件。

除了使用FormData接口上传,也可以直接使用File API上传。

var file = document.getElementById('test-input').files[0];
var xhr = new XMLHttpRequest();

xhr.open('POST', 'myserver/uploads');
xhr.setRequestHeader('Content-Type', file.type);
xhr.send(file);

可以看到,上面这种写法比FormData的写法,要简单很多。

3 表单的验证

3.1 HTML 5表单验证

所谓“表单验证”,指的是检查用户提供的数据是否符合要求,比如Email地址的格式。HTML 5原生支持表单验证,不需要JavaScript。

<input type="date" >

上面代码指定该input输入框只能填入日期,否则浏览器会报错。

但有时,原生的表单验证不完全符合需要,而且出错信息无法指定样式。这时,可能需要使用表单对象的noValidate属性,将原生的表单验证关闭。

var form = document.getElementById("myform");
form.noValidate = true;

form.onsubmit = validateForm;

上面代码先关闭原生的表单验证,然后指定submit事件时,让JavaScript接管表单验证。

此外,还可以只针对单个的input输入框,关闭表单验证。

form.field.willValidate = false;

每个input输入框都有willValidate属性,表示是否开启表单验证。对于那些不支持的浏览器(比如IE8),该属性等于undefined。

麻烦的地方在于,即使willValidate属性为true,也不足以表示浏览器支持所有种类的表单验证。比如,Firefox 29不支持date类型的输入框,会自动将其改为text类型,而此时它的willValidate属性为true。为了解决这个问题,必须确认input输入框的类型(type)未被浏览器改变。

if (field.nodeName === "INPUT" && field.type !== field.getAttribute("type")) {
    // 浏览器不支持该种表单验证,需自行部署JavaScript验证
}

3.2 checkValidity方法,setCustomValidity方法,validity对象

checkValidity方法表示执行原生的表单验证,如果验证通过返回true。如果验证失败,则会触发一个invalid事件。使用该方法以后,会设置validity对象的值。

每一个表单元素都有一个validity对象,它有以下属性。

  • valid:如果该元素通过验证,则返回true。
  • valueMissing:如果用户没填必填项,则返回true。
  • typeMismatch:如果填入的格式不正确(比如Email地址),则返回true。
  • patternMismatch:如果不匹配指定的正则表达式,则返回true。
  • tooLong:如果超过最大长度,则返回true。
  • tooShort:如果小于最短长度,则返回true。
  • rangeUnderFlow:如果小于最小值,则返回true。
  • rangeOverflow:如果大于最大值,则返回true。
  • stepMismatch:如果不匹配步长(step),则返回true。
  • badInput:如果不能转为值,则返回true。
  • customError:如果该栏有自定义错误,则返回true。

setCustomValidity方法用于自定义错误信息,该提示信息也反映在该输入框的validationMessage属性中。如果将setCustomValidity设为空字符串,则意味该项目验证通过。

4 在JavaScript中访问表单或表单域

  •  通过document.forms[]按编号访问
  • 通过document.forms[]按名称访问
  • 在支持DOM的浏览器中,使用document.getElementById()

 例如:

<form name="form1" method="post" action="">

<input type="text" name="text1"/>

</form>

访问表单:可以使用window.document.forms[0]或window.document.forms['form1'],或者使用window.document.form1来访问表单

访问表单域:可以使用window.document.form1.text1访问值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值