Javascript中的Form表单知识点总结

Javascript中的Form表单知识点总结

     在HTML中,表单是由form元素来表示的,但是在javascript中,表单则由HTMLFormElement类型,此元素继承了HTMLElement,因此与其他HTML元素具有相同的默认属性;HTMLFormElement有自己以下属性和方法;

acceptCharset: 服务器能够处理的字符集;等价于HTML中的accept-charset特性;

action:  接收请求的URL,等价于HTML中的action

elements: 表单中所有控件的集合.

enctype: 请求的编码类型;等价于HTML中的enctype特性;

length: 表单中控件的数量;

method 要发送的http请求类型,一般是get或者是post,等价于HTML中的method;

name: 表单的名称;

reset(): 将所有表单域重置为默认值;

submit(): 提交表单;

target:用于发送请求和接收响应的窗口名称;

如何获取form表单的引用?

假如现在页面上有一个form表单元素,html代码如下:

<form id="form" name="form1">form>

我现在想取到上面的form表单的引用,一共有以下方式可以获取到上面 的form表单引用;

1. 通过获取form表单的id,来获取form表单的引用;如下代码:

var formId = document.getElementById("form");
console.log(formId);

2. 通过document.forms 取得页面中的所有表单元素,然后通过索引来取到对应的form元素,如下代码所示:取得页面第一个form元素;

console.log(document.forms[0]);

3. 通过from表单中的name属性来获取,代码如下:

console.log(document.forms['form1']);

如何提交表单

下面的所有事件都是来自上一篇博客javascript事件总结的事件,都依赖于此封装的事件,代码如下:

var EventUtil = {
    addHandler: function(element,type,handler) {
        if(element.addEventListener) {
            element.addEventListener(type,handler,false);
        }else if(element.attachEvent) {
            element.attachEvent("on"+type,handler);
        }else {
            element["on" +type] = handler;
        }
    },
    removeHandler: function(element,type,handler){
        if(element.removeEventListener) {
            element.removeEventListener(type,handler,false);
        }else if(element.detachEvent) {
            element.detachEvent("on"+type,handler);
        }else {
            element["on" +type] = null;
        }
    },
    getEvent: function(event) {
        return event ? event : window.event;
    },
    getTarget: function(event) {
        return event.target || event.srcElement;
    },
    preventDefault: function(event){
        if(event.preventDefault) {
            event.preventDefault();
        }else {
            event.returnValue = false;
        }
    },
    stopPropagation: function(event) {
        if(event.stopPropagation) {
            event.stopPropagation();
        }else {
            event.cancelBubble = true;
        }
    },
    getRelatedTarget: function(event){
        if (event.relatedTarget){
            return event.relatedTarget;
        } else if (event.toElement){
            return event.toElement;
        } else if (event.fromElement){
            return event.fromElement;
        } else {
            return null;
        }
    },
    getWheelDelta: function(event) {
        if(event.wheelDelta) {
            return event.wheelDelta;
        }else {
            return -event.detail * 40
        }
    },
    getCharCode: function(event) {
        if(typeof event.charCode == 'number') {
            return event.charCode;
        }else {
            return event.keyCode;
        }
    }
};

用户单击提交按钮或图像按钮时,就会提交表单,使用input或者button都可以提交表单,只需将type设置为submit或者image即可,如下三种方式都可以;

第一种:

<form id="form" name="form1" action="http://www.baidu.com">
    
    <input type="text">
    <input type="submit" value="submit">
form>

第二种:

<form id="form" name="form1" action="http://www.baidu.com">
    
    <input type="text">
    <button type="submit">submitbutton>
form>

第三种:

<form id="form" name="form1" action="http://www.baidu.com">
    
    <input type="text">
    <input type="image" src="aa.jpg">
form>

我们也可以通过如下方式提交表单,但是也可以阻止form表单提交:如下代码:

EventUtil.addHandler(formId,"submit",function(event){
    // 取得事件对象
    event = EventUtil.getEvent(event);
    // 阻止默认事件
    EventUtil.preventDefault(event);
});

如何重置表单

如果我们使用按钮重置表单的话,有下面2种方式:

第一种代码如下:

<form id="form" name="form1" action="http://www.baidu.com">
    <input type="text">
    <input type="reset" value="reset">
form>

第二种代码如下:

<form id="form" name="form1" action="http://www.baidu.com">
    <input type="text">
    <button type="reset">resetbutton>
form>

我们也可以通过像提交form表单一样来进行重置表单,代码如下:

var formId = document.getElementById("form");
formId.reset();

如何访问表单字段?

第一种方式我们可以使用dom节点来访问;

第二种方式:每个表单都有elements属性,该属性是表单中所有表单元素的集合;这个elements是个有序列表;包含着所有字段,比如有input,textarea,button,fieldset等;

比如如下HTML代码:

<form id="form" name="form1" action="http://www.baidu.com">
    <input type="text" name="input1">
    <select name="select1">
        <option>111option>
    select>
form>

JS获取表单字段如下:

var formId = document.getElementById("form");
// 取得表单中的第一个字段
var firstCol = formId.elements[0];
console.log(firstCol);
// 取得名字name为select1的字段
console.log(formId.elements['select1']);
// 取得表单中包含字段的数量
console.log(formId.elements.length);

如果一个表单中,有多个name相同的属性,那么取得数据是一个集合,如下HTML代码:

<form id="form" name="form1" action="http://www.baidu.com">
    <input type="radio" name="radio2"/>
    <input type="radio" name="radio2"/>
    <input type="radio" name="radio2"/>
form>

JS代码如下:

var formId = document.getElementById("form");
var radios = formId.elements["radio2"];
console.log(radios.length);  // 打印3

共有的表单字段属性

所有的表单字段都有一组相同的属性;表单共有的属性如下:

disabled: 布尔值,表示当前字段是否被禁用;

form: 指向当前字段所属表单的指针,只读;

name: 当前字段的名称;

readOnly:布尔值,表示当前字段是否可读。

tabIndex: 表示当前字段的切换(tab)序号。

type: 当前字段的类型,如checkbox,radio等;

value: 当前字段被提交到服务器的值;

共有的表单字段方法

每个表单字段都有两个方法focus()和blur(),其中focus是获取焦点;比如在页面加载完成后,我希望form表单中的第一个字段获取焦点(除隐藏域之外);如下代码:

<form id="form" name="form1" action="http://www.baidu.com">
    <input type="text" name="radio2"/>
    <input type="text" name="radio2"/>
    <input type="text" name="radio2"/>
form>

JS代码如下

var formId = document.getElementById("form");
EventUtil.addHandler(window,'load',function(event){
    formId.elements[0].focus();
});

但是HTML5中为表单字段新增了一个autofocus属性,在支持这个属性浏览器中,如果设置了这个属性,不用javascript就能将焦点移动到某个输入框下,比如如下HTML代码,在页面加载完成后,我把焦点放在第二个输入框内,如下HTML代码:

<form id="form" name="form1" action="http://www.baidu.com">
    <input type="text" name="radio2" />
    <input type="text" name="radio2" autofocus/>
    <input type="text" name="radio2"/>
form>

支持autofocus属性的浏览器有:firefox4+,safari5+,chrome和Opera9.6+

但是我想要兼容其他不支持autofocus的浏览器,我们可以写一段JS,为了全兼容;

var formId = document.getElementById("form");
EventUtil.addHandler(window,'load',function(event){
    var element = formId.elements[1];
    if(element.autofocus !== true) {
        element.focus();
    }
});

因为autofocus是一个布尔值,支持他的浏览器默认为true;不支持他的浏览器,默认值为空字符串;

共有的表单字段事件

所有的表单字段都支持以下三个事件;

blur:当前字段失去焦点时触发;

change:对于input和textarea元素,值发生改变的时候触发;

focus: 当前字段获得焦点时触发;

理解文本框脚本

在HTML中,有2种方式来实现文本框,一种是input元素的单行文本框,另一种是textarea元素的多行文本框;

input元素有属性type=”text”, 还可以通过设置size属性,用来指定文本框显示的字符数,还可以设置value,用来显示文本框的初始值,还可以设置maxlength属性,用于指定文本框可以接受的最大字符数;如下代码:

多行文本框textarea也有一些属性,这里就不做多介绍了;

如何选择文本:

input和select两种元素都支持select()方法,这个方法用于选择文本框中的所有文本,在调用select()方法中(除Opera外),都会将焦点设置到文本框中,这个方法不接受任何参数,如下代码:

<form id="formId">
    <input type="text" name="input" value="我是龙恩"/>
form>

JS代码如下:

var formId = document.getElementById("formId");
formId.elements['input'].select();

如下图所示:

如上是页面一进来的时候,默认选择input元素框所有的内容;我们也可以当获取焦点的时候,就选中所有的内容,JS代码可以改为如下:

var formId = document.getElementById("formId"),
input = formId.elements['input'];
EventUtil.addHandler(input,"focus",function(event){
    event = EventUtil.getEvent(event);
    var target = EventUtil.getTarget(event);
    target.select();
});

在火狐和谷歌浏览器下能实现当获取焦点的时候,就选中input元素框内的所有内容,但是在IE7或者8下,还是页面加载完后就已经选中了文本框内的所有元素;

  1.   选择事件(select)

与select方法对应的,还有一个select事件,在IE9+,firefox,chrome,opera和safari中,只有用户选择了文本且释放鼠标时,会触发select事件;但是在IE8及以下,只要用户选择了一个字母且不必释放鼠标,就会触发select事件;如下代码:

var formId = document.getElementById("formId"),
input = formId.elements['input'];
EventUtil.addHandler(input,"select",function(event){
    alert(input.value);
});

2. 取的选择的文本

虽然通过select事件我们知道用户什么时候选择了文本,但是我们并不知道用户选择了什么文本,在HTML5中,我们通过两个属性selectionStart和selectionEnd,这两个属性表示选择的范围(即文本区开头和结尾的偏移量);因此要取得用户选择的文本,可以使用如下代码;

var formId = document.getElementById("formId"),
    input = formId.elements['input'];
EventUtil.addHandler(input,"select",function(event){
    alert(getSelectedText(input));
});
function getSelectedText(elem) {
    return elem.value.substring(elem.selectionStart,elem.selectionEnd);
}

但是目前浏览器支持程度有:IE9+,firefox,chrome,Opera及safari;

IE8及之前的版本不支持这两个属性,但是他们提供了另外一种document.selection对象,其中保存着用户在整个文档范围内选择的文本信息,但是呢与前面的select事件使用在一起的话,只能选择一个字符就会触发事件,也就是说,不能选择大于1和字符的文字,不过可以知道选择的值时多少;如下代码:

var formId = document.getElementById("formId"),
input = formId.elements['input'];
EventUtil.addHandler(input,"select",function(event){
    alert(getSelectedText(input));
});
function getSelectedText(elem) {
    if(typeof elem.selectionStart == "number") {
         return elem.value.substring(elem.selectionStart,elem.selectionEnd);
    }else if(document.selection) {
        return document.selection.createRange().text;
    }
}

选择部分文本

HTML5也为选择文本框中的部分文本提供了解决方案,使用setSelectionRange()方法,这个方法接收2个参数,要选择的第一个字符的索引,和要选择的最后一个字符之后的字符的索引;

浏览器支持有:IE9+,chrome,safari和opera,firefox貌似不支持;

代码如下:

var formId = document.getElementById("formId"),
    input = formId.elements['input'];
input.value = "我是龙恩,我是中国人";
// 选择所有文本
input.setSelectionRange(0,input.value.length);

截图如下:

// 选择前3个字符

input.setSelectionRange(0,3);

截图如下:

// 选择第四到第六个字符

input.setSelectionRange(4,7);

截图如下:

IE8及以下版本可以使用范围来选择部分文本,要选择部分文本,必须首先使用IE在所有文本框中提供的createTextRange()方法创建一个范围,且我们需要使用collapse()将范围折叠到文本框的开始位置,再使用moveStart()和moveEnd()这两个范围方法将范围移动到位;

如下代码选择所有的文本:

input.value = "我是龙恩,我是中国人";
var range = input.createTextRange();
// 选择所有文本
range.collapse(true);
range.moveStart("character",0);
range.moveEnd("character",input.value.length);
range.select();

演示如下:

切记:使用F5刷新没有用的,要在地址栏中,然后按enter键刷新即可看到效果;

// 选择前3个字符
range.collapse(true);
range.moveStart("character",0);
range.moveEnd("character",3);
range.select();

演示如下:

// 选择第4到第6个字符
range.collapse(true);
range.moveStart("character",4);
range.moveEnd("character",3);
range.select();

演示如下:

为了让跨浏览器效果,我们可以封装一个方法,如下:

function selectText(elem,startIndex,stopIndex) {
    if(elem.setSelectionRange) {
          elem.setSelectionRange(startIndex,stopIndex);
    }else if(elem.createTextRange) {
        var range = elem.createTextRange();
        range.collapse(true);
        range.moveStart("character",startIndex);
        range.moveEnd("character",stopIndex - startIndex);
        range.select();
    }
}

测试数据如下:貌似firefox不支持

// 选择所有文本
selectText(input,0,input.value.length);
        
// 选择前3个字符
selectText(input,0,3);

// 选择第四个字符到第六个字符
selectText(input,4,7);

过滤输入

    有时候我们会要求用户在输入框里面输入特定格式的数据,我们就可以使用过滤输入这种手段来进行了,首先我们来看看如何屏蔽字符;

 1.   屏蔽字符

比如我在一个input输入框中,只允许只能输入数字,那么我们可以先获取通过keypress事件来监听,然后每次获取到键码,然后通过String.fromCharCode()这个方法,把键码转换成字符串,然后通过正则判断下,如果不是数字,直接阻止默认事件即可不让用户输入,如下代码:

<form id="formId">
    <input type="text" name="input"/>
form>

JS代码如下:

var formId = document.getElementById("formId"),
input = formId.elements['input'];    
EventUtil.addHandler(input,'keypress',function(event) {
    event = EventUtil.getEvent(event);
    var charCode = EventUtil.getCharCode(event);
    if(!/\d/.test(String.fromCharCode(charCode))) {
        EventUtil.preventDefault(event);
    }
});    

如上代码能满足日常需求,但是有些游览器,比如firefox,safari(3.1版本之前)会对向上键,向下键,退格键和删除键也会触发keypress事件了;所以为了避免这些事件的发生,我们需要做一些处理来满足所有版本的浏览器的需求,我们发现在firefox中,所有由非字符键触发keypress键码都为0;而在safari3以前的版本中,对应的字符编码全部为8;所以我们要对字符编码进行判断下;

如下代码:

EventUtil.addHandler(input,'keypress',function(event) {
    event = EventUtil.getEvent(event);
    var charCode = EventUtil.getCharCode(event);
    if(!/\d/.test(String.fromCharCode(charCode)) && charCode > 9) {
        EventUtil.preventDefault(event);
    }
});

操作剪贴板

到目前为止,IE,chrome,safari,opera都支持剪贴板事件,貌似firefox就不支持了(书上说支持);但是我操作就不支持了;下面是6个操作剪贴板事件;如下:

beforecopy: 在发生复制操作前触发;

copy: 在发生复制操作时触发;

beforecut: 在发生剪贴操作前触发;

cut: 在发生剪贴操作时触发;

beforepaste: 在发生黏贴操作前触发;

paste: 在发生粘帖操作时触发;

针对上面的事件,我们可以使用如下代码测试下就可以证明了;代码如下所示:

EventUtil.addHandler(input,'beforecopy',function(event) {
    alert(1);
});

如果要访问剪贴板中的数据,可以使用clipboardData对象,在IE中,这个对象是window对象的属性,在safari或者chrome上,这个对象是event的属性,这个clipboardData对象有三个方法,getData(),setData(),和clearData();

getData()是从剪贴板中取得数据,他接受一个参数,即要取得数据的格式,在IE中,有二种数据格式”text” 和 “url”,在safari和chrome中这个参数是一种MIME类型,不过,可以使用text代表text/plain.

setData()方法是给剪贴板设置文本,接受2个参数,第一个数据是数据类型;第二个参数是放在剪贴板中的文本;但是此方法接受的数据类型只能是text/plain,不能是text;因此为了全兼容浏览器(出firefox外),我们可以写一个通用的方法出来,如下:

getClipboardText: function(event) {
    var clipboardData = (event.clipboardData || window.clipboardData);
        return clipboardData.getData("text");
    },
setClipboardText:function(event,value) {
    if(event.clipboardData) {
        return event.clipboardData.setData("text/plain",value);
    }else if(window.clipboardData) {
        return window.clipboardData.setData("text",value);
    }
}

因此EventUtil封装的所有方法如下:

var EventUtil = {
    addHandler: function(element,type,handler) {
        if(element.addEventListener) {
                    element.addEventListener(type,handler,false);
        }else if(element.attachEvent) {
            element.attachEvent("on"+type,handler);
        }else {
            element["on" +type] = handler;
        }
    },
    removeHandler: function(element,type,handler){
        if(element.removeEventListener) {
                    element.removeEventListener(type,handler,false);
        }else if(element.detachEvent) {
            element.detachEvent("on"+type,handler);
        }else {
            element["on" +type] = null;
        }
    },
    getEvent: function(event) {
        return event ? event : window.event;
    },
    getTarget: function(event) {
        return event.target || event.srcElement;
    },
    preventDefault: function(event){
        if(event.preventDefault) {
            event.preventDefault();
        }else {
            event.returnValue = false;
        }
    },
    stopPropagation: function(event) {
        if(event.stopPropagation) {
            event.stopPropagation();
        }else {
            event.cancelBubble = true;
        }
    },
    getRelatedTarget: function(event){
        if (event.relatedTarget){
            return event.relatedTarget;
        } else if (event.toElement){
            return event.toElement;
        } else if (event.fromElement){
            return event.fromElement;
        } else {
            return null;
        }
    },
    getWheelDelta: function(event) {
        if(event.wheelDelta) {
            return event.wheelDelta;
        }else {
            return -event.detail * 40
        }
    },
    getCharCode: function(event) {
        if(typeof event.charCode == 'number') {
            return event.charCode;
        }else {
            return event.keyCode;
        }
    },
    getClipboardText: function(event) {
        var clipboardData = (event.clipboardData || window.clipboardData);
        return clipboardData.getData("text");
    },
    setClipboardText:function(event,value) {
        if(event.clipboardData) {
        return event.clipboardData.setData("text/plain",value);
            }else if(window.clipboardData) {
            return window.clipboardData.setData("text",value);
        }
    }
};

测试代码如下:还是上面测试输入框的值是否为数字;每次粘帖上次,都能获取到黏贴的是文字数据,代码如下:

HTML代码如下:

<form id="formId">
     <input type="text" name="input"/>
form>

JS代码如下:

var formId = document.getElementById("formId"),
input = formId.elements['input'];
EventUtil.addHandler(input,'paste',function(event) {
    event = EventUtil.getEvent(event);
    var text = EventUtil.getClipboardText(event);
    alert(text);
    if (!/^\d*$/.test(text)){
        EventUtil.preventDefault(event);
    }
});

理解自动切换输入框或者textarea的焦点

比如我们在填写表单的页面上,当用户输入完自己的数据的时候,不需要用户手动切换到下一个输入框里面去,我们可以自动切换去,这样的话,对于用户体验来说,比较方便,比如我们现在页面上有一个form表单,这里为了做测试,我们先用一个输入框用于手机号码的,另外一个是textarea,当手机号码输入11位数字后,会自动切换到textarea中;当然页面中的隐藏域除外;代码如下:

HTML代码如下:

<form id="formId">
    <input type="text" name="input" maxlength=11/>
    <textarea>textarea>
form>

JS代码如下:

var formId = document.getElementById("formId"),
input = formId.elements['input'];
EventUtil.addHandler(input,'keyup',tabForward);
function tabForward(event) {
    event = EventUtil.getEvent(event);
    var target = EventUtil.getTarget(event);
    if(target.value.length == target.maxLength) {
        // 获取当前的form表单的引用
        var form = target.form;
        for(var i = 0, ilen = form.elements.length; i < ilen; i++) {
            if(form.elements[i] == target) {
                if(form.elements[i+1]) {
                    form.elements[i+1].focus();
                }
                return;
            }
        }        
    }
}

理解HTML5新增属性

required属性;

比如在HTML5中对表单input,textarea,或者select标签的话,提交表单时,需要判断是否为空,特别对于在做移动端的朋友来说,可以使用HTML5中的新增属性required;如下HTML代码:

<form id="formId">
    <input type="text" name="input" maxlength=11 required/>
    <textarea>textarea>
    <input type="submit"/>
form>

提交时候,在chrome下看到效果如下:

Javascript中的Form表单知识点总结_第1张图片

在firefox下,提示如下:

Javascript中的Form表单知识点总结_第2张图片

如上是根据不同的浏览器本身的性质来提示的,因此样式不同,所以适合在移动端根据本身浏览器内核来提示;

但是在Javascript是如何判断的呢?比如如下HTML代码:

<form id="formId">
    <input type="text" name="input" maxlength=11 required/>
    <textarea>textarea>
    <input type="submit" name="submit"/>
form>

JS代码如下:

var formId = document.getElementById("formId"),
submit = formId.elements['submit'];
EventUtil.addHandler(submit,'click',function(event) {
    var isRequired = formId.elements["submit"].required;
    console.log(isRequired);
});

如上打印出false;可以获取到submit的属性required,如果输入框值为空的话,会打印出false出来;

如果想知道浏览器是否支持required这个属性的话,我们可以使用如下代码判断下,如果返回true,说明支持,否则不支持;如下:

var isRequiredSupported = "required" in document.createElement("input");
console.log(isRequiredSupported);

input输入框类型type的值是email或者url

email类型要求输入的文本必须符合电子邮件的格式,url类型要求输入的文本必须符合URL的格式;如下chrome浏览器截图如下;

Javascript中的Form表单知识点总结_第3张图片

Javascript中的Form表单知识点总结_第4张图片

选择框脚本

选择框是通过