JavaScript基础——表单脚本

虽然HTML和Web应用自诞生以来已经发生了天翻地覆的变化,但Web表单相对却没有什么改变。

使用JavaScript可以增强已有的表单字段,从而创造出新的功能,或者提升表单的易用性。

为此,表单、表单字段都引入了相应的属性和方法,以便JavaScript使用。下面介绍几个概念:

1)可以使用一些标准或非标准的方法选择文本框中的部分或部分文本。

2)大多数浏览器都采用了Firefox操作选择文本的方式,但ie仍然坚持自己的实现。

3)在文本框的内容变化时,可以通过侦听键盘事件以及检测插入的字符,来允许或禁止用户输入的某些字符。

除Opera之外的所有浏览器都支持剪贴板事件,包括copy、cut和paste.其他浏览器在实现剪贴板事件时也可以分

以下几种不同的情况:

1)IE、Firefox、Chrome和Safari允许通过JavaScript访问剪贴板中的数据,而Opera不允许这种访问方式。

2)即使是IE、Chrome和Safari,它们各自的实现方式也不相同。

3)Firefox、Chrome和Safari只允许在paste事件发生时读取剪贴板数据,而IE没有这个限制。

4)Firefox、Chrome和Safari只允许在发生剪贴板事件时访问与剪贴板相关的信息,而IE允许在任何时候访问相关信息。

在文本框内容必须限制为某些特定字符的情况下,就可以利用剪贴板事件来屏蔽通过粘贴向文本框中插入内容的操作。

选择框也是经常要通过JavaScript来控制的一个表单字段。由于有了DOM,对选择框的操作比以前要方便多了。

添加选项、移除选项、将选项从一个选择框移动到另一个选择框,甚至对选项进行排序等操作,都可以使用标准的DOM技术来实现。

富文本编辑功能是通过一个包含空HTML文档的iframe元素来实现的。通过将空文档的designMode属性设置为"on",就可以将该页面转换为可编辑状态,此时其表现如同字处理软件。另外,也可以将某个元素设置为contenteditable。

在默认情况下,可以将字体加粗或者将文本转换为斜体,还可以使用剪贴板。JavaScript通过使用execCommand()方法也可以实现相同的一些功能。另外,使用queryCommandEnabled()、queryCommandState()和queryCommandValue()方法则可以取得有关文本选区的信息。由于以这种方式构建的富文本编辑器并不是一个表单字段,因此在将其内容提交给服务器之前,必须将iframe或contenteditable元素中的HTML复制到一个表单字段中。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>表单脚本</title>
    <style>
        .editable{
            width:100px;
            height: 100px;
            border: 1px solid green;
        }
    </style>
</head>
<body>
<form name="myForm" id="myForm">
    <!--通用提交按钮-->
    <input type="submit" value="提交表单">
    <!--自定义提交按钮-->
    <button type="submit">提交表单</button>
    <!--图像按钮-->
    <input type="image" src="submit.png">
    <!--通用重置表单-->
    <input type="reset" value="重置表单">
    <!--自定义重置表单-->
    <button type="reset">重置表单</button>

    <input type="text" name="textBox">
    <!--自动获取焦点-->
    <input type="text" autofocus>
    <input type="submit" value="确定" name="submit_btn">
    <!--自定义文本框-->
    <input type="text" size="25" maxlength="50" value="文本框" name="textbox1">
    <textarea rows="5" cols="25">多行文本框</textarea>
    <input type="text" name="textbox2">

    <input type="text" name="tel1" id="txtTel1" maxlength="3">
    <input type="text" name="tel2" id="txtTel2" maxlength="3">
    <input type="text" name="tel3" id="txtTel3" maxlength="4">

    <!--填字段必-->
    <input type="text" name="username" required>
    <!--html5指定输入类型-->
    <input type="email" name="email">
    <input type="url" name="homepage">
    <!--指定用户输入0~100之间5的倍数的值-->
    <input type="number" min="0" max="100" step="5" name="count">
    <!--只允许输入数值-->
    <input type="text" pattern="\d+" name="count">

    <!--选择框-->
    <select name="location" id="selLocation">
        <option value="上海">上海</option>
        <option value="北京">北京</option>
        <option value="深圳">深圳</option>
        <option value="">中国</option>
        <option>意大利</option>
    </select>

    <!--富文本编辑-->
    <div class="editable" id="richedit" contenteditable></div>
</form>
<script src="l14.js"></script>
</body>
</html>
/**
 * 表单脚本
 */
function cl(x){
    console.log(x);
}
//跨浏览器事件对象
var EventUtil={
    //添加事件监听
    addHandler:function(element,type,handler){
        if(element.addEventListener){
            element.addEventListener(type,handler,false);//w3c
        }else if(element.attachEvent){
            element.attachEvent("on"+type,handler);//IE
        }else{
            element["on"+type]=handler;//低版本浏览器
        }
    },
    //获取事件元素
    getEvent:function(event){
        return event?event:window.event;
    },
    //获取事件目标
    getTarget:function(event){
        return event.target||event.srcElement;
    },
    //阻止默认事件
    preventDefault:function(event){
        if(event.preventDefault){
            event.preventDefault();//W3C
        }else{
            event.returnValue=false;//IE
        }
    },
    //移除事件监听
    removeHandler:function(element,type,handler){
        if(element.removeEventListener){
            element.removeEventListener(type,handler,false);//W3C
        }else if(element.detachEvent){
            element.detachEvent("on"+type,handler);//IE
        }else{
            element["on"+type]=null;//低版本浏览器
        }
    },
    //阻止冒泡
    stopPropagation:function(event){
        if(event.stopPropagation){
            event.stopPropagation();//W3C
        }else{
            event.cancelBubble=true;//IE
        }
    },
    //相关元素属性
    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;
        }
    },
    //获取鼠标按钮属性
    getButton:function(event){
        if(document.implementation.hasFeature("MouseEvents","2.0")){
            return event.button;
        }else{//IE8及以下
            switch (event.button){
                case 0:
                case 1:
                case 3:
                case 5:
                case 7:
                    return 0;
                case 2:
                case 6:
                    return 2;
                case 4:
                    return 1;
            }
        }
    },
    //获取鼠标滚轮事件属性
    getWheelDelta:function(event){
        if(event.wheelDelta){
            return (client.engine.opera && client.engine.opera<9.5 ?
                -event.wheelDelta: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);
        }
    }
};

/**
 *14.1 表单的基础知识
 */
//HTMLFormElement有独有的属性和方法
//acceptCharset、action、element、enctype、length、method、name、reset()、submit()、target
//取得<form>元素引用的方式:
var form=document.getElementById("myForm");
var firstForm=document.forms[0];
var myForm=document.forms["myForm"];
//14.1.1 提交表单
//form.submit();
//如何阻止表单提交
var form=document.getElementById("myForm");
EventUtil.addHandler(form,"submit",function(event){
    //取得事件对象
    event=EventUtil.getEvent(event);
    //阻止默认事件
    EventUtil.preventDefault(event);
});
//如何不让用户重复提交表单
//1.在第一次提交表单后就禁用提交按钮;2.利用onsubmit事件处理程序取消后续的表单提交操作
//14.1.2 重置表单(慎用)
//form.reset();
//阻止重置表单
var form=document.getElementById("myForm");
EventUtil.addHandler(form,"reset",function(event){
    //取得事件对象
    event=EventUtil.getEvent(event);
    //阻止默认事件
    EventUtil.preventDefault(event);
});
//14.1.3 表单字段
//每个表单都有elements属性,该属性是表单中所有元素的集合
var form=document.getElementById("myForm");
//取得表单中的第一个字段
var field1=form.elements[0];
//取得名为"textBox"的字段
var field2=form.elements["textBox"];
//取得表单中包含的字段的数量
var filedCount=form.elements.length;
//14.1.3.1 共有的表单字段属性
//disabled、form、name、readOnly、tabIndex、type、value
//通过js动态修改字段的属性
var form=document.getElementById("myForm");
var field=form.elements[0];
field.value="确认提交";//修改value属性
cl(field.form===form);//=>true 检查form属性的值
field.disabled=true;//禁用当前字段
field.type="email";//修改type属性
//避免多次提交表单
EventUtil.addHandler(form,"submit",function(event){
    event=EventUtil.getEvent(event);
    var target=EventUtil.getTarget(event);
    //取得提交按钮
    var btn=target.elements["submit_btn"];
    //禁用按钮
    btn.disabled=true;
});
//14.1.3.2 共有的表单字段方法
//focus()、blur()
//侦听load事件,在指定字段上调用focus方法
EventUtil.addHandler(window,"load",function(event){
    var element=document.forms[0].elements["textBox"];
    if(element.autofocus!==true){
        element.focus();
    }
});
//14.1.3.3 共有的表单字段事件
//focus事件、blur事件、change事件
var textBox=document.forms[0].elements["textBox"];
//获取焦点时设置背景色
EventUtil.addHandler(textBox,"focus",function(event){
    event=EventUtil.getEvent(event);
    var target=EventUtil.getTarget(event);
    if(target.style.backgroundColor!="red"){
        target.style.backgroundColor="yellow";
    }
});
//失去焦点时改变背景色
EventUtil.addHandler(textBox,"blur",function(event){
    event=EventUtil.getEvent(event);
    var target=EventUtil.getTarget(event);
    if(/[^\d]/.test(target.value)){//输入非数字后失去焦点,背景变红
        target.style.backgroundColor="red";
    }else{//输入的是数字失去焦点,背景恢复为无
        target.style.backgroundColor="";
    }
});
//改变文本内容时改变背景色
EventUtil.addHandler(textBox,"change",function(event){
    event=EventUtil.getEvent(event);
    var target=EventUtil.getTarget(event);
    if(/[^\d]/.test(target.value)){//输入非数字后失去焦点,背景变红
        target.style.backgroundColor="red";
    }else{//输入的是数字失去焦点,背景恢复为无
        target.style.backgroundColor="";
    }
});

/**
 * 14.2 文本框脚本
 */
var textbox1=document.forms[0].elements["textbox1"];
cl(textbox1.value);
textbox1.value="新的文本框";
cl(textbox1.value);
//14.2.1 选择文本
//调用select()方法,可以把焦点设置到文本框中
EventUtil.addHandler(textbox1,"focus",function(event){
    event=EventUtil.getEvent(event);
    var target=EventUtil.getTarget(event);
    //获得焦点即选中所有的文本
    target.select();
});
//14.2.1.1 选择(select)事件
EventUtil.addHandler(textbox1,"select",function(event){
    cl("文本框选中了:"+textbox1.value);
});
//14.2.1.2 取得选择的文本
function getSelectedText(textBox){
    return textBox.value.substring(textBox.selectionStart,textBox.selectionEnd);
}
//14.2.1.3 选择部分文本
textbox1.value="Hello world";
//选择所有文本
var str1=textbox1.setSelectionRange(0,textbox1.value.length);
//选择前3个字符
var str2=textbox1.setSelectionRange(0,3);

//14.2.2 过滤输入
//14.2.2.1 屏蔽字符
var textbox2=document.forms[0].elements["textbox2"];
EventUtil.addHandler(textbox2,"keypress",function(event){
   event=EventUtil.getEvent(event);
    var target=EventUtil.getTarget(event);
    var charCode=EventUtil.getCharCode(event);
    //只允许用户输入数值
    if(!/\d/.test(String.fromCharCode(charCode)) && charCode>9 && !event.ctrlKey){
        EventUtil.preventDefault(event);
    }
});
//14.2.2.2 操作剪贴板
//剪贴板事件:beforecopy、copy、beforecut、cut、beforepaste、paste
EventUtil.addHandler(textbox2,"paste",function(event){
    event=EventUtil.getEvent(event);
    var text=EventUtil.getClipboardText(event);
    if(!/^\d*$/.test(text)){
        EventUtil.preventDefault(event);
    }
});

//14.2.3 自动切换焦点
(function(){
    function tabForward(event){
        event=EventUtil.getEvent(event);
        var target=EventUtil.getTarget(event);
        if(target.value.length==target.maxLength){
            var form=target.form;
            for(var i= 0,len=form.elements.length;i<len;i++){
                if(form.elements[i]==target){
                    if(form.elements[i+1]){
                        form.elements[i+1].focus();
                    }
                    return;
                }
            }
        }
    }
    var textbox1=document.getElementById("texTel1");
    var textbox2=document.getElementById("texTel2");
    var textbox3=document.getElementById("texTel3");

    EventUtil.addHandler(textbox1,"keyup",tabForward);
    EventUtil.addHandler(textbox2,"keyup",tabForward);
    EventUtil.addHandler(textbox3,"keyup",tabForward);
})();

//14.2.4 HTML5约束验证API
//14.2.4.1 必填字段
//检查某个表单字段是否为必填字段
var isUsernameRequired=document.forms[0].elements["username"].required;
//测试浏览器是否支持required属性
var isRequiredSupported="required" in document.createElement("input");
//14.2.4.2 其他输入类型 email、url
//测试浏览器是否支持email类型
var input=document.createElement("input");
input.type="email";
var isEmailSupported=(input.type=="email");
//14.2.4.3 数值范围
//14.2.4.4 输入模式
//访问字段的pattern属性
var pattern=document.forms[0].elements["count"].pattern;
//检测浏览器是否支持pattern属性
var isPatternSupported="pattern" in document.createElement("input");
//14.2.4.5 检测有效性
//checkValidity()方法 validity属性
if(input.validity && !input.validity.valid){
    if(input.validity.valueMissing){
        alert("请输入一个值");
    }else if(input.validity.typeMismatch){
        alert("请输入一个email")
    }else{
        alert("没有输入值");
    }
}
//14.2.4.6 禁用验证
//form标签中加novalidate属性
//input标签中formnovalidate属性
document.forms[0].noValidate=true;
document.forms[0].elements["btnNoValidate"].formNoValidate=true;

/**
 * 14.3 选择框脚本
 */
//HTMLSelectElement类型提供了下列属性和方法:
//add(newOption,relOption)、multiple、options、remove(index)、selectedIndex、size
//<option>元素都有一个HTMLOptionElement对象,有下列属性
//index、label、selected、text、value
var selectbox=document.forms[0].elements["location"];
var text=selectbox.options[0].text; //选项的文本
var value=selectbox.options[0].value; //选项的值
//14.3.1 选择选项
//获得选中项
var selectedOption=selectbox.options[selectbox.selectedIndex];
//显示选中项的信息
cl("选项序号:"+selectbox.selectedIndex+"\n 选项文本:"+
    selectedOption.text+"\n选项值:"+selectedOption.value);
//取得所有选中的项
function getSelectedOptions(selectbox){
    var result=new Array();
    var option=null;
    for(var i= 0,len=selectbox.options.length;i<len;i++){
        option=selectbox.options[i];
        if(option.selected){
            result.push(option);
        }
    }
    return result;
}
//14.3.2 添加选项:add()方法、insertBefore()方法
var newOption=new Option("选项文本","选项值");
selectbox.add(newOption,undefined);//最佳方案
//14.3.3 移除选项:remove()方法
function clearSelectbox(selectbox){
    for(var i= 0,len=selectbox.options.length;i<len;i++){
        selectbox.remove(i);
    }
}
//14.3.4 移动和重排选项
//将第一个选择框中的第一个选项移动到第二个选择框中
var selectbox1=document.getElementById("selLocations1");
var selectbox2=document.getElementById("selLocations2");
selectbox2.appendChild(selectbox1.options[0]);
//在选择框中向前移动一个选项的位置
var optionToMove=selectbox.options[1];
selectbox.insertBefore(optionToMove,selectbox.options[optionToMove.index-1]);

/**
 * 14.4 表单序列化
 */
function serialize(form){
    var parts=[],
    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);
                            }
                            parts.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){
                    parts.push(encodeURIComponent(field.name)+"="+encodeURIComponent(optValue));
                }
        }
    }
    return parts.join("&");
}

/**
 * 14.5 富文本编辑
 */
//designMode属性
EventUtil.addHandler(window,"load",function(){
    frames["richedit"].document.designMode="on";
});
//14.5.1 使用contenteditable属性
var richedit=document.getElementById("richedit");
richedit.contentEditable="true";
//14.5.2 操作富文本
//document.execCommand()
//转换粗体文本
document.execCommand('bold',false,null);
//转换斜体文本
document.execCommand('italic',false,null);
//创建指向www.baidu.com的链接
document.execCommand("createlink",false,"http://www.baidu.com");
//格式化为1级标题
document.execCommand("formatblock",false,"<h1>");
//14.5.3 富文本选区
//使用框架(iframe)的getSelection()方法
//14.5.4 表单与富文本
EventUtil.addHandler(form,"submit",function(event){
    event=EventUtil.getEvent(event);
    var target=EventUtil.getTarget(event);
    target.elements["comments"].value=document.getElementById("richedit").innerHTML;
})



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值