• 表单的常用操作


    知识点:

    表单是前后端数据交互的一种重要方式,使用js操作表单也是十分常见的。不过好像每次到表单操作我都要去查API,所以本次想对表单的常用操作做个小结,以备后面随时查看。

    首先,我们要知道如下的一些知识:

    1. 表单字段在向后台提交数据时,使用的是表单控件的name属性的value,与id无关。(大家可以在百度搜细说表单找到Fish Li大神的这篇文章看看)

    2. 表单向服务端传数据时会经过编码。目前基本上只会只使用二种编码规则:application/x-www-form-urlencoded 和 multipart/form-data , 这二个规则的使用场景简单地说就是:后者在上传文件时使用,其它情形则使用前者(默认)。当使用ajax的post方式向后端传数据时,也会常常设置其header头来模拟表单的数据提交方式:xhr.setRequestHeader(‘cotent-type’, ‘application/x-www-form-urlencoded ’);这样后端程序就可以像处理表单数据那种处理传过来的参数了

    3. 表单字段共有的属性包括:

    ① disbled: 布尔值,表示当前字段是否禁用

    ② readOnly: 布尔值,表示当前字段是否是只读的

    ③ type: 当前字段类型,对input元素来说,type属性就等于其html中写定的type属性,如text, password, checkbox, radio, submit, textarea..

    但要注意select元素的type,对于单选的select元素,其type为select-one, 多远的select元素,type为select-multiple

    ④ 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;
    }

    练习时的源代码:下载地址

  • 相关阅读:
    linux离线安装nodejs ,配置环境,离线配置全局包
    前端项目路由使用browserHistory不能刷新,页面刷新错误,
    手机uc浏览器打不开本地网页,网页一片空白
    display:flex兼容性,
    react生产环境样式丢失问题 在浏览器中看到标签有类名,但没有样式
    redux使用redux-thunk中间件处理异步状态管理请求
    配置Redux DevTools
    flex-grow属性在文本过长时会超出父窗体长度
    react配置代理,解决跨域
    react修改状态
  • 原文地址:https://www.cnblogs.com/jagusOu/p/3801614.html
Copyright © 2020-2023  润新知