第十四章:表单脚本(表单的基础知识)

表单脚本

  • JavaScript最初的一个应用,就是分担服务器处理表单的责任,打破处处依赖服务器的局面。由于Web表单没有为许多常见任务提供现成的解决手段,很多开发人员不仅会在验证表单的时候使用JavaScript,而且还增强了一些标准表单控件的默认行为。

表单的基础知识

  • 在HTML中,表单是由<form>元素来表示的。在JavaScript中,表单对应的是HTMLFormElement 类型。HTMLFormElement继承自HTMLElement,下面是HTMLFormElement独有的属性和方法。
    1. acceptCharset:服务器能处理的字符集;等价于HTML中的accept-charset特性。
    2. action:接受请求的URL。等价于action特性。
    3. elements:表单中所有控件的集合(HTMLCollection)。
    4. enctype:请求的编码类型;等价于enctype特性。
    5. length:表单中控件的数量(重点内容)。
    6. method:要发送的HTTP请求类型,通常是get或者post;等价于method特性。
    7. name:表单的名称。等价于name特性。
    8. reset():将所有表单域重置为默认值。
    9. submit():提交表单。
    10. target:用于发送请求接收响应窗口名称。等价于target特性。
  • 取得表单的引用除了通用的方法外,还可以通过document.forms取得页面中所有表单。在这个集合中,我们可以通过索引或者name特性来取得表单。
  • 有些较早的浏览器也会把每个设置了name特性的表单作为属性保存在document中,所以也可以通过document.formname获得表单名为formname的引用。但这种做法并不推荐。

提交表单

  • 用户单击提交按钮图像按钮时,就会提交表单。
    <!-- 通用提交按钮 -->
    <input type="submit" value="Submit Form">
    <!-- 自定义提交按钮 在Chrome中type的缺省值为submit-->
    <button type="submit">Submit Form</button>
    <!-- 图像按钮 当图片不存在时,会显示"提交"二字(类似img的alt属性),否则显示图片-->
    <input type="image" src="graphic.gif">
  • 当表单中存在上述按钮,在表单控件拥有焦点的情况下,按回车键(可以认为绑定了keydown或keyup事件)就可以提交表单(textarea 是一个例外,在文本区中回车会换行)。如果没有按钮,按回车键不会提交表单。
  • 通过上述方式提交表单会在表单提交前到服务器之前触发submit事件。这样,我们就可以验证表单数据来决定是否取消提交表单。
    var form = document.getElementById("myForm");
    form.addEventListener("submit", function(event){
        //阻止默认事件
        event.preventDefault();
    });
  • 除此之外,还可以通过submit()方法手动提交表单。这种方法无需表单包含提交按钮。缺点是不会触发submit事件,需要在调用这个方法之前,手动验证表单数据是否有效。
    var form = document.getElementById("myForm");
    if (true) {
        form.submit();
    }
  • 提交表单的最大问题是重复提交。在第一次提交表单后,如果长时间没有反应,用户可能会变得不耐烦。这时候,他们也许会反复单击提交按钮。在这里我们可以禁用该按钮或者通过onsubmit 事件处理程序取消后续的表单提交操作。

重置表单

  • 用户单击重置按钮时,表单会被重置。所谓重置,就是如果某个字段的初始值为空,就恢复为空。如果有默认值,就恢复为默认值。
    <!-- 通用重置按钮 -->
    <input type="reset" value="Reset Form">
    <!-- 自定义重置按钮 -->
    <button type="reset">Reset Form</button>
  • 用户单击重置按钮重置表单时,会触发reset 事件。利用这个机会,我们可以在必要时取消重置操作。另外,通过reset()方法也可以重置表单,与submit()不同的是,调用这个方法会触发reset事件(submit()不会触发submit事件):
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form id="myForm">
        <input type="text" value="1">
        <input type="text" >
        <!-- 通用提交按钮 -->
        <input type="submit" value="Submit Form">
        <!-- 自定义提交按钮 -->
        <button type="submit">Submit Form</button>
        <!-- 图像按钮 -->
        <input type="image" src="graphic.gif">
        <!-- 通用重置按钮 -->
        <input type="reset" value="Reset Form">
        <!-- 自定义重置按钮 -->
        <button type="reset">Reset Form</button>
        <!-- 不加上type="button" 会被认为是submit按钮 -->
        <!-- 也可以写成this.form.reset();后面会学到form属性指向包含该表单元素的表单-->
        <button type="button" onclick="this.parentNode.reset()">reset</button>
    </form>
    <script>
        var form = document.getElementById("myForm");
        form.addEventListener("submit", function(event){
            alert("submit");
            //阻止默认事件
            event.preventDefault();
        });
        form.addEventListener("reset", function(event){
            alert("reset");
            //阻止表单重置
            event.preventDefault();
        });
    </script>
</body>
</html>

表单字段

  • 前面提到过,取得表单引用后,我们可以通过form.elements获得表单元素集合。这个集合包含表单中所有字段,例如<input>、<textarea>、<button>和<fieldset>。我们可以用花括号语法获得对应的表单元素(通过索引或者name值)。特别的,如果有多个表单控件都在使用一个name(如单选按钮),那么form.elements[“ename”]将会返回一个NodeList。看下面的例子:
<!DOCTYPE html>
<html>
<head>
    <title>Form Fields Example</title>
</head>
<body>
    <form method="post" action="javascript:alert('Form submitted!')" id="myForm">
        <ul>
            <li><input type="radio" name="color" value="red">Red</li>
            <li><input type="radio" name="color" value="green">Green</li>
            <li><input type="radio" name="color" value="blue">Blue</li>
        </ul>
    </form>     
    <script type="text/javascript">
        (function(){
            var form = document.getElementById("myForm");
            var colorFields = form.elements["color"];//NodeList
            alert(colorFields.length);  //3
            var firstColorField = colorFields[0];
            var firstFormField = form.elements[0];
            alert(firstColorField === firstFormField);   //true
            alert(form.elements[1] === colorFields[1]);   //true
        })();
    </script>
</body>
</html>
  • 上面这个例子比较简单,就不解析了。另外需要注意的是:旧浏览器支持直接通过form[0]或者form[“color”]取得表单元素(为保证兼容现代浏览器也可以这么使用)。这种做法和通过elements属性获得表单元素是一样的。将上面的代码修改之后依然可以正常运行,但不推荐这种做法。
    <script type="text/javascript">
        (function(){
            var form = document.getElementById("myForm");
            var colorFields = form["color"];
            alert(colorFields.length);  //3
            var firstColorField = colorFields[0];
            var firstFormField = form[0];
            alert(firstColorField === firstFormField);   //true
            alert(form[1] === colorFields[1]);   //true
        })();
    </script>
共有的表单字段属性
  • 除了<fieldset>元素之外,所有表单字段都拥有相同的一组属性。由于<input>类型可以表示多种表单字段(type),因此有些属性只适用于某些字段,但还有一些属性是所有字段所共有的。表单字段共有的属性如下。
    1. disabled:布尔值,表示当前字段是否被禁用。
    2. form:指向当前字段所属表单的指针;只读。
    3. name:当前字段的名称。
    4. readOnly:布尔值,表示当前字段是否只读。
    5. tabIndex:表示当前字段的切换(tab)序号。
    6. type:当前字段的类型,如”checkbox”、”radio”,等等。
    7. value:当前字段将被提交给服务器的值。对文件字段来说,这个属性是只读的,包含着文件在计算机中的路径。
  • 除了form之外,其余属性都可以修改:
var form = document.getElementById("myForm");
var field = form.elements[0];
//修改value 属性
field.value = "Another value";
//检查form 属性的值
alert(field.form === form); //true
//把焦点设置到当前字段
field.focus();
//禁用当前字段
field.disabled = true;
//修改type 属性(不推荐,但对<input>来说是可行的)
field.type = "checkbox";
  • 所以我们也可以通过disabled属性解决之前的重复提交问题:
    (function(){
        var form = document.forms[0];
        //Code to prevent multiple form submissions
        form.addEventListener("submit", function(event){
            var target = event.target;//submit的target为form引用
            //get the submit button(name为submit-btn)
            var btn = target.elements["submit-btn"];
            //disable it
            btn.disabled = true;
        });
    })();
  • 有人说上面这段代码也可以注册为submit-btnonclick事件处理程序。但它的缺点有两个:
    1. 如果我用submit()提交(当表单获得焦点时按回车,会触发提交按钮(第一个提交按钮)的onclick事件),自然是无法触发按钮的click事件的(但因为submit事件也不会触发,所以也不算是一个缺点)。
    2. 部分浏览器会先触发click事件再触发submit事件。而由于触发submit事件时,按钮已经禁用,故导致永远也无法提交表单。例如下面的代码,在IE9+和Firefox中能正常提交表单,在Chrome则不行。
<!DOCTYPE html>
<html>
<head>
    <title>Form Fields Example</title>
    <script type="text/javascript" src="EventUtil.js"></script>
</head>
<body>
    <form method="post" action="javascript:alert('Form submitted!')" id="myForm">
        <ul>
            <li><input type="radio" name="color" value="red">Red</li>
            <li><input type="radio" name="color" value="green">Green</li>
            <li><input type="radio" name="color" value="blue">Blue</li>
        </ul>
        <input type="submit" value="Submit Form" name="submit-btn">
        <button type="button">Whatever</button>
    </form>     
    <script type="text/javascript">
        (function(){
            var form = document.forms[0];
            form.elements["submit-btn"].onclick = function () {
                this.disabled = true;
            }
        })();
    </script>
</body>
</html>
  • 除了<fieldset>之外,所有表单字段都有type 属性。对于<input>元素,这个值等于HTML 特性type 的值。对于其他元素,见下面的例子:
<form id="myForm">
    <!--单选列表-->
    <select><option>1</option><option>2</option></select>
    <!--多选列表-->
    <select multiple><option>1</option><option>2</option></select>
    <!--自定义按钮,默认为submit-->
    <button>自定义按钮</button>
    <!--自定义非提交按钮 -->
    <button type="button">自定义非提交按钮</button>
    <!--自定义重置按钮 -->
    <button type="reset">自定义重置按钮</button>
    <!--自定义提交按钮 -->
    <button type="submit">自定义提交按钮</button>
</form>
<script>
    var form = document.getElementById("myForm");
    for (var i=0,len = form.elements.length;i<len;i++) {
        console.log(form.elements[i].type);
    }
</script>
----------------------------
select-one
select-multiple
submit
button
reset
submit
  • 此外,input和button元素的type是可以修改的,而select元素的type属性是只读的。
共有的表单字段方法
  • 每个表单字段都有两个方法:focus()blur()。看看名字就知道是什么用处了。需要注意的是,调用type为hidden的input元素focus()会发生错误。同样的,如果使用CSS的display和visibility属性隐藏了该字段,也会发生错误。
  • HTML5 为表单字段新增了一个autofocus 属性。在支持这个属性的浏览器中,只要设置这个属性,不用JavaScript 就能自动把焦点移动到相应字段。例如<input type="text" autofocus>
  • 与focus()方法相对的是blur()方法,它的作用是从元素中移走焦点。在早期Web开发中,那时候的表单字段还没有readonly特性,因此就可以用blur()方法来创建只读字段(没有焦点就无法通过键盘输入)。现在一般很少用这个方法了。
    //elements[0]是一个type="text"的input元素
    document.forms[0].elements[0].onfocus = function () {
        this.blur();
    }
共有的表单字段事件
  • 除了支持鼠标、键盘、更改和HTML 事件之外,所有表单字段都支持下列3 个事件。
    1. blur:当前字段失去焦点时触发。
    2. focus:当前字段获得焦点时触发。
    3. change:对于<input><textarea>元素,在它们失去焦点且value 值改变时触发(触发change事件和blur事件的先后顺序不同浏览器有所不同,参考:Chrome、Firefox、IE9+先change再blur);对于<select>元素,在其选项改变时触发。
  • 当用户改变了当前字段的焦点,或者我们调用了blur()或focus()方法时,都可以触发blur 和focus 事件
  • 通常,可以使用focus 和blur 事件来以某种方式改变用户界面,要么是向用户给出视觉提示,要么是向界面中添加额外的功能(例如,为文本框显示一个下拉选项菜单)。而change 事件则经常用于验证用户在字段中输入的数据。
  • 由于很常用,我就不举例子了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值