表單的經常使用操做

知識點:

表單是先後端數據交互的一種重要方式,使用js操做表單也是十分常見的。不過好像每次到表單操做我都要去查API,因此本次想對錶單的經常使用操做作個小結,以備後面隨時查看。html

首先,咱們要知道以下的一些知識:ios

1. 表單字段在向後臺提交數據時,使用的是表單控件的name屬性的value,與id無關。(你們能夠在百度搜細說表單找到Fish Li大神的這篇文章看看)ajax

 

2. 表單向服務端傳數據時會通過編碼。目前基本上只會只使用二種編碼規則:application/x-www-form-urlencoded 和 multipart/form-data , 這二個規則的使用場景簡單地說就是:後者在上傳文件時使用,其它情形則使用前者(默認)。當使用ajax的post方式向後端傳數據時,也會經常設置其header頭來模擬表單的數據提交方式:xhr.setRequestHeader(‘cotent-type’, ‘application/x-www-form-urlencoded ’);這樣後端程序就能夠像處理表單數據那種處理傳過來的參數了後端

 

3. 表單字段共有的屬性包括:數組

① disbled: 布爾值,表示當前字段是否禁用服務器

② readOnly: 布爾值,表示當前字段是不是隻讀的app

③ type: 當前字段類型,對input元素來講,type屬性就等於其html中寫定的type屬性,如text, password, checkbox, radio, submit, textarea..post

但要注意select元素的type,對於單選的select元素,其type爲select-one, 多遠的select元素,type爲select-multiplethis

④ name:當前字段的名稱,也是做爲有效控件默認向服務器傳送數據時的key編碼

⑤ value: 對多遠的select元素的value,select.value只能取到第一個選中option的value; 要獲取checkbox和radio的value只有經過遍歷。除此以外,其它元素的value便是將發向服務器的value,能夠經過element.value直接獲得

⑥ tabIndex: 當前字段的tab切換序號

⑦ form: 字段所屬的表單

除了form屬性不能寫以外,其它共有屬性都是可讀寫的

 

4 . 表單字段共的有方法有:focus(), blur()

 

5. 表單字段共有的事件有:focus, blur, change

 

6. select元素的額外方法:

除了表單字段共有的屬性和方法外,select元素還有下列屬性和方法:

① add(newOption, relOption), 向select元素中插入新的option, 新插入的option的位置在relOption以前

② opitions: 獲得全部的option的HTMLCollection

③ remove(index): 移除指定位置的option

④ selectIndex: 獲取選中項的索引(從0開始),若沒有選中項,返回-1,對於支持多選項的select,返回第一個選中的項

⑤ size: 選擇框中可見的行數,等價於HTML中的size屬性

⑥ select的type屬性爲select-one/select-multiple

⑦ 若是沒有選中項,select的value爲空字符串 (「」);若是有一個選中項,且其option的value已經指定,則select的value爲選中的option的value, 即便選中的option的value的值爲空串;若選中的option的value值沒有指定,則select的value爲此option的文本;如有多個選中項,select的value以第一個選中的項爲準

 

對於option元素,爲了方便訪問數據,HTMLOptionElement包含了如下屬性:

① index: 此選項在options集合中的索引

② label:此選項的標籤,等價於HTML中的label特性

③ selected:此選項是否被選中

④ text: 此選項的文本

⑤ value:此選項的值,等價於HTML中的value

 

實際練習

select操做封裝:

select: {
    //select操做
    addItem: function(select, value, text, pos) {
        var option = document.createElement('option');
        option.setAttribute('value', value);
        option.innerHTML = text;
        if(pos) {
            select.insertBefore(option, select.querySelectorAll('option')[pos]);
        }
        //注意這裏傳了一個undefined參數,
        select.add(option, undefined);
        return option;
    },
    removeItem: function(select, index) {
        //可使用select.options訪問全部的options元素
        select.removeChild(select.options[index]);
        //select.remove(index) 這樣也能夠
    },
    selectItemByIndex: function(select, index) {
        var options = select.options;
         options[index].selected = true;
    },
    selectItemByVal: function(select, val) {
        var options = select.options, index;
        for(var i = 0, l = options.length; i < l; i++) {
            if(options[i].value === val) {
                index = i;
                break;
            }
        }
        this.selectItemByIndex(select, index);
    },
    val: function(select, value) {
        if(value) {
            this.selectItemByVal(select, value);
        } else {
            return select.value;
        }

    },
    getSelectedIndex: function(select) {
        //獲取當前選中項的索引, 若是對象有設置mutiple屬性,則返回一個索引數組
        var ret = [], i = 0, options, temp;

        if(! select.multiple) {
            return select.selectedIndex;
        }

        options = select.options;
        while(temp = options[i]) {
            if(temp.selected)
                ret.push(i)
            i++;
        }
        return ret;
    }
}

checkbox封裝:

checkbox: {
    all: function(checkboxs, flag) {
        //全選, 全不選, flag === true,全選中, flag === false,全不選
        var checkbox, i = 0;
        while(checkbox = checkboxs[i]) {
            checkbox.checked = flag;
            i++;
        }
    },
    inverse: function(checkboxs) {
        //反選
        var checkbox, i = 0;
        while(checkbox = checkboxs[i]) {
            checkbox.checked = !checkbox.checked;
            i++;
        }
    },
    selectItemByVal: function(checkboxs, val) {
        var index;
        for(var i = 0, l = checkboxs.length; i < l; i++) {
            if(checkboxs[i].value === val) {
                checkboxs[i].checked = true;
                break;
            }
        }
    }
}

radio封裝

radio: {
    selectItemByIndex: function(radios, index) {
        if(radios[index]) {
            radios[index].checked = true;
        }
    },
    selectItemByVal: function(radios, val) {
        var index;
        for(var i = 0, l = radios.length; i < l; i++) {
            if(radios[i].value === val) {
                radios[i].checked = true;
                break;
            }
        }
    }
}

取得有效表單控件的name和value,組成一個dataMap

dataMap: function(form) {
    //取得把有效的表單控件的name和值,組成一個數據map
    var nameMap = {},
        dataMap = {}, name, _slice = [].slice;

    //查找表單中有效的表單控件:
    /**
     * 什麼是有效表單控件(參考Fish Li博客-細說表單):
     1. 控件不能是【禁用】狀態,即指定【disabled="disabled"】。即:禁用的控件將不是成功控件。
     2. 若是一個表單包含了多個提交按鍵,那麼僅當用戶點擊的那個提交按鈕纔算是成功控件。
     3. 對於checkbox控件來講,只有被用戶勾選的纔算是成功控件。
     4. 對於radio button來講,只有被用戶勾選的纔算是成功控件。
     5. 對於select控件來講,全部被選擇的選項都作爲成功控件,name由select控件提供。
     6. 對於file上傳文件控件來講,若是它包含了選擇的文件,那麼它將是一個成功控件。
     */

        //收集input元素的name
    _slice.call(form.querySelectorAll('input')).forEach(function(e, i) {
        var name = e.name;
        if(! nameMap[name])
            nameMap[name] = name;
    });

    //收集select元素的name
    _slice.call(form.querySelectorAll('select')).forEach(function(e, i) {
        var name = e.name;
        if(! nameMap[name])
            nameMap[name] = name;
    });

    //收集textarea
    _slice.call(form.querySelectorAll('textarea')).forEach(function(e, i) {
        var name = e.name;
        if(! nameMap[name])
            nameMap[name] = name;
    });

    //遍歷nameMap,並取得相應的表單控件的值,組成dataMap
    for(name in nameMap) {
        if(nameMap.hasOwnProperty(name)) {
            _slice.call(document.getElementsByName(name)).forEach(function(e, i) {
                if(e.type === 'checkbox'|| e.type === 'radio') {
                    //可能多遠
                    dataMap[name] = dataMap[name] || [];
                    if(e.checked) {
                        dataMap[name].push(e.value);
                    }
                } else if(e.type === 'select-multiple') {
                    //注意能夠多選的select的type屬性爲 select-multiple
                    //可能多選
                    dataMap[name] = dataMap[name] || [];
                    _slice.call(e.options).forEach(function(e, i) {
                        if(e.selected) {
                            dataMap[name].push(e.value);
                        }
                    });
                } else {
                    dataMap[name] = e.value;
                }
            })
        }
    }
    return dataMap;
}

練習時的源代碼:下載地址

相關文章
相關標籤/搜索