Javascript中的Form表單知識點總結

龍恩0707發表於2015-05-17

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放在這,為了獲取焦點,然後我們可以按enter鍵提交 -->
    <input type="text">
    <input type="submit" value="submit">
</form>

第二種:

<form id="form" name="form1" action="http://www.baidu.com">
    <!-- 存放一個input放在這,為了獲取焦點,然後我們可以按enter鍵提交 -->
    <input type="text">
    <button type="submit">submit</button>
</form>

第三種:

<form id="form" name="form1" action="http://www.baidu.com">
    <!-- 存放一個input放在這,為了獲取焦點,然後我們可以按enter鍵提交 -->
    <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">reset</button>
</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>111</option>
    </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屬性,用於指定文字框可以接受的最大字元數;如下程式碼:

<input type="text" size="2" maxlength='12' value=""/>

多行文字框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下看到效果如下:

在firefox下,提示如下:

如上是根據不同的瀏覽器本身的性質來提示的,因此樣式不同,所以適合在移動端根據本身瀏覽器核心來提示;

但是在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

<input type=”email” name=”email”/>

<input type=”url” name=”url”/>

email型別要求輸入的文字必須符合電子郵件的格式,url型別要求輸入的文字必須符合URL的格式;如下chrome瀏覽器截圖如下;

選擇框指令碼

選擇框是通過<select>和<option>元素建立的,除了表單所有的共有屬性和方法外,HTMLSelectElement類還提供了下列屬性和方法;

add(newOption,relOption);向控制元件中插入新<option>元素,其位置在relOption之前;

multiple:布林值; 表示是否允許多項選擇,等價於HTML中的multiple特性;

options: 控制元件中所有<option>元素的HTMLCollection;

remove(index):   移除給定位置的選項;

selectedIndex:   基於0的選中索引,如果沒有該選項,則值為 -1;

size:  選擇框中的可見的行數。

如下select框程式碼:

<form id="formId">
    <select name="location" id="selLocation">
        <option value="A">A</option>
        <option value="B">B</option>
        <option value="C">C</option>
        <option value="">D</option>
        <option>E</option>
    </select>
</form>

JS程式碼如下:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
console.log(select.value);
EventUtil.addHandler(select,'change',function(){
    console.log(select.value)
});

第一次頁面載入完成後,列印出值為A;

當每次切換的時候,如果有value就列印出值,如果value=””;則列印空字串,但是如果option選項沒有指定value,在firfox和chrome下列印出當前的文字值,比如上面的文字為E,則值為E;但是IE8及以下,列印的還是空字串;

在DOM中,每個<option>元素都有一個HTMLOptionElement物件表示;為方便訪問資料,物件新增了如下屬性;

index: 當前選項在options集合中的索引;

label 當前選項的標籤,等價於HTML中的label

selected布林值,表示當前選項是否被選中,將這個屬性設定為true可以選中當前選項。

text選項的文字;

value選項的值;

我們還是以上面的form表單作為HTML程式碼,我們使用JS來測試下:

如下程式碼:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
// 獲取options集合中的第一項選項的文字
console.log(select.options[0].text);   // 列印出A
// 獲取options集合中的第一項選項的value
console.log(select.options[0].value);  // 列印出A

對於下拉框只能選擇一項的選擇框,訪問最簡單的方式,就是使用selectedIndex屬性,如下HTML程式碼:

<form id="formId">
    <select name="location" id="selLocation">
        <option value="A">A</option>
        <option value="B" selected>B</option>
        <option value="C">C</option>
        <option value="">D</option>
        <option>E</option>
    </select>
</form>

如頁面初始化的時候預設選擇第二項,那麼我們可以先使用selectedIndex的屬性獲取選中的索引,然後根據索引獲取當前的文字和值;如下JS程式碼:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
// 獲取當前選中的選項的索引selectedIndex
var selectedIndex = select.selectedIndex;
// 獲取索引為selectedIndex的option
var selectedOption = select.options[selectedIndex];    
console.log("selected index:"+selectedIndex+"\nselect text:"+selectedOption.text+"\nselect value:"+selectedOption.value);

新增選項

可以使用javascript動態建立選項,並將它們新增到選擇框中,新增選擇框有以下常見3種方式;

第一種方式使用DOM的方式如下:

HTML程式碼如下:

<form id="formId">
    <select name="location" id="selLocation">
            
    </select>
</form>

JS程式碼如下:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
var newOption = document.createElement("option");
newOption.appendChild(document.createTextNode("A"));
newOption.setAttribute("value","AAAA");
select.appendChild(newOption);

第二種方式使用Option建構函式來建立新選項,Option建構函式接收2個引數,文字(text)和值(value),第二個引數可選,比如如下程式碼:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
var newOption = new Option("Option text","Option value");
select.appendChild(newOption);

但是這種方式在IE下是不生效的;

下面我們來看看第三種方式吧!是使用選擇框add()方法,DOM規定這個方法接收2個引數,要新增的新選項和將位於新選項之後的選項,如果想在列表的最後新增一個選項,應將第二個引數設定為null;在IE對add()方法的實現中,第二個引數是可選的,但是標準DOM瀏覽器中,必須要指定第二個引數,因此為了全相容瀏覽器,我們必須新增第二個引數,但是我們可以將第二個引數設定為undefined,含義是:在所有的瀏覽器將新選項插入到列表的最後了~

如下程式碼:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
var newOption = new Option("Option text","Option value");
select.add(newOption,undefined);

移除選項的方式如下:

  1. 使用dom的removeChild()方法,為其傳入要移除的選項;如下程式碼:

HTML程式碼如下:

<form id="formId">
    <select name="location" id="selLocation">
        <option value="A">A</option>
        <option value="B">B</option>
        <option value="C">C</option>
    </select>
</form>

Javascript程式碼如下:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
// 第一種:移除第一項如下方式
select.removeChild(select.options[0]);

2. 第二種方式是使用選擇框的remove()方法,這個方法接收一個引數,既要移除選項的索引;如下程式碼:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
// 移除第一項
select.remove(0);

3. 最後一種方式,就是將相應的選項設定為null,如下程式碼:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
// 移除第一項
select.options[0] = null;

理解表單序列化

在javascript中,可以利用表單欄位的type屬性,連同name和value屬性一起實現對錶單的序列化,序列化後將把這些資料傳送給伺服器。

下面是將那些欄位需要進行序列化的;

  1. 對錶單欄位的名稱和值進行URL編碼,使用&分割;
  2. 不傳送禁用的表單欄位;
  3. 只傳送勾選的單選框和核取方塊按鈕資料;
  4. 不傳送type為reset和button的按鈕
  5. 多選選擇框中的每個選中的值單獨一個條目;
  6. Select元素的值,就是選中option元素的value的值,如果option沒有屬性value,則是選中的文字值;

如下JS程式碼是封裝form表單的序列化的JS如下:

// 序列化JS程式碼封裝

function serialize(form) {
    var arrs = [],
    field = null,
    i,
    len,
    j,
    optLen,
    option,
    optValue;
    for(i = 0,len = form.elements.length; i < len; i++) {
        field = form.elements[i];
        switch(field.type) {
            case "select-one":
               case  "select-multiple":
            if(field.name.length) {
                 for(j = 0,optLen = field.options.length; j < optLen; j++) {
                       option = field.options[j];
                       if(option.selected) {
                           optValue = '';
                           if(option.hasAttribute) {
                               optValue = option.hasAttribute("value") ? option.value : option.text;
                           }else {
                               optValue = option.attributes["value"].specified ? option.value : option.text;
                           }
                           arrs.push(encodeURIComponent(field.name) + "=" +encodeURIComponent(optValue));
                       }
                   }
             }
            break;
            case undefined:      //欄位集
            case "file":         // 檔案輸入
            case "submit":       // 提交按鈕
            case "reset":        // 重置按鈕
            case "button":       // 自定義按鈕
            break;
                    
            case "radio":        // 單選框
            case "checkbox":     // 核取方塊
            if(!field.checked) {
                break;
            }
            /* 執行預設動作 */
           default:
           // 不包含沒有名字的表單欄位
           if(field.name.length) {
               arrs.push(encodeURIComponent(field.name) + "=" +encodeURIComponent(field.value));
           }
       }
    }
    return arrs.join("&");
}

     如上對form表單序列化的函式serialize,定義了一個arrs陣列,用來儲存需要序列化後的名值對,然後通過for迴圈迭代每個表單中的欄位,先使用臨時變數field儲存表單中任意一個欄位的引用,然後使用switch語句判斷欄位的型別type(如果type未定義的話,此元素就不需要表單序列化),第一種情況是select的單選和多選框,對於select單選框,只可能有一個選中項,對於多選框可能有零或多個選中項,如果有選中項的話(通過屬性selected來判斷),需要確定使用什麼值,如果不存在value特性,或者雖然存在該特性,但是值為空字串,都是使用選項的文字來代替,為檢查這個特性,在相容DOM的瀏覽器下我們需要使用hasAttribute()方法,而在IE中需要使用特性的specified屬性;對於type=“file”或者submit,reset,button等就不支援,如果比如上傳圖片的時候,需要圖片的二進位制資料使用form表單提交的話,可以在序列化後在加上這個引數即可;對於單選框和核取方塊如果沒有選中的話,同樣不進行序列化;下面我們現在來看看一個demo吧!如下HTML程式碼:

<form id="formId">
    <select name="location" id="selLocation" one="one">
        <option value="A">A</option>
        <option value="B">B</option>
        <option value="C">C</option>
    </select>
    <select multiple="multiple" style="width: 50px;" id="mymultiple" name="select2">
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
        <option>5</option>
    </select>
    <input name="a" type="radio"/>
    <input name="b" type="checkbox"/>
    <input type="file" name="aaaa">
    <input type="hidden" name="hidden" value="hidden"/>
    <input type="submit" value="提交" name="submit"/>
</form>

JS程式碼如下:

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

我們看到上面的form表單程式碼,上面有select單選框,也有select多選框,也有隱藏域和input框,但是請注意:上面name=”a”和name=”b”,當他們選中的時候,沒有值屬性,所以在各個瀏覽器上都會自帶一個值為on的值傳給伺服器端,但是這個並不是我們想要的,所以的如果需要值的話,一定要設定值,如下如下截圖:

在火狐和谷歌下截圖如下:

在IE下:

上面的select多選框,如果需要多選的話,記得先要按住鍵盤上的ctrl鍵就可以多選了,比如上面的select2=2&select2=3&select2=4 就是select框多選。

理解富文字編輯

在網頁中編輯內容,IE最早引入這個功能,隨後opera,safari,firefox和chrome也實現了這個功能,基本原理就是在頁面中嵌入一個空HTML頁面的iframe,通過設定designMode屬性,這個空白的HTML頁面可以新增文字,而新增文字則是該頁面的body元素的html程式碼,如下所示:

designMode有2個屬性,off(預設值)和on, 當設定為on的時候,整個文件變得可編輯,但是我們也可以給他們新增css樣式,為了更加美觀;首先我們先來看看demo,如下HTML頁面巢狀一個iframe;

<iframe name="richedit" src="bank.html"></iframe>

而bank.html頁面是一個空頁面,程式碼如下:

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>Document</title>
 </head>
 <body>
    
 </body>
</html>

然後在主頁面上使用JS,當頁面載入完成後,將designMode屬性設定為on即可,如下JS程式碼:

EventUtil.addHandler(window,'load',function(event){
    frames['richedit'].document.designMode = "on";
});

然後在頁面上顯示如下:

第二種實現方式是使用contenteditable屬性來實現

contenteditable屬性是有IE最早實現的,可以把contenteditable屬性給頁面中的任何元素,然後使用者可以立即編輯該元素,不需要iframe,空頁面及JS,只需要使用contenteditable屬性即可;如下程式碼給div設定contenteditable屬性;如下程式碼:

<div class="richedit" contenteditable style="width:100px;height:100px;border:1px solid #ccc"></div>

在瀏覽器下效果如下:

支援的瀏覽器有;IE,firefox,chrome,safari和opera;

在移動裝置上,有ios5+和Android3+;

Contenteditable屬性有三個可能值,true表示開啟,false表示關閉,inherit表示從父元素那邊繼承。

相關文章