美文网首页JavaScript < ES5、ES6、ES7、… >
JavaScript 高级程序设计(第14章 表单脚本)

JavaScript 高级程序设计(第14章 表单脚本)

作者: yinxmm | 来源:发表于2018-08-17 11:29 被阅读29次

    第14章 表单脚本

    1. 表单的基础指示

    在 JavaScript 中,表单对应的则是 HTMLFormElement类型。HTMLFormElement 继承了 HTMLElement,因而与其他 HTML 元素具有相同的默认属 性。

    HTMLFormElement 自己独有的属性和方法:

    (1) acceptCharset:服务器能够处理的字符集;等价于 HTML 中的 accept-charset 特性。
    (2) action:接受请求的 URL;等价于 HTML 中的 action 特性。
    (3) elements:表单中所有控件的集合(HTMLCollection)。
    (4) enctype:请求的编码类型;等价于 HTML 中的 enctype 特性。
    (5) length:表单中控件的数量。
    (6) method:要发送的 HTTP 请求类型,通常是"get"或"post";等价于 HTML 的 method 特性。
    (7) name:表单的名称;等价于 HTML 的 name 特性。
    (8) reset():将所有表单域重置为默认值。
    (9) submit():提交表单。
    (10) target:用于发送请求和接收响应的窗口名称;等价于 HTML 的 target 特性。

    取得<form>元素引用的方式:

    1. getElementById()方法
    var form = document.getElementById("form1");
    
    1. 通过 document.forms 可以取得页面中所有的表单。在这个集合中,可以通过数值索引或name 值来取得特定的表单。
    var firstForm = document.forms[0]; //取得页面中的第一个表单
    var myForm = document.forms["form2"]; //取得页面中名称为"form2"的表单
    

    (1) 提交表单

    1. 用户单击提交按钮图像按钮时,就会提交表单。使用<input>或<button>都可以定义提交按钮, 只要将其 type 特性的值设置为"submit"即可,而图像按钮则是通过将<input>的 type 特性值设置为"image"来定义的。
    <!-- 通用提交按钮 -->
    <input type="submit" value="Submit Form">
    <!-- 自定义提交按钮 -->
    <button type="submit">Submit Form</button>
    <!-- 图像按钮 -->
    <input type="image" src="graphic.gif">
    
    1. 提交表单时,浏览器会在将请求发送给服务器之前触发 submit 事件
    var form = document.getElementById("myForm");
    EventUtil.addHandler(form, "submit", function(event){
        //取得事件对象
        event = EventUtil.getEvent(event);
        //阻止默认事件
        EventUtil.preventDefault(event);
    });
    
    1. 在 JavaScript 中,以编程方式调用 submit()方法也可以提交表单。(以调用 submit()方法的形式提交表单时,不会触发 submit 事件)
    var form = document.getElementById("myForm");
    //提交表单
    form.submit();
    
    1. 避免重复提交表单的方法:在第一次提交表单后就禁用提交按钮,或者利用 onsubmit 事件处理程序取消后续的 表单提交操作。

    (2) 重置表单

    1. 在用户单击重置按钮时,表单会被重置。使用 type 特性值为"reset"的<input>或<button>都可以创建重置按钮。
    <!-- 通用重置按钮 -->
    <input type="reset" value="Reset Form">
    <!-- 自定义重置按钮 -->
    <button type="reset">Reset Form</button>
    
    1. 用户单击重置按钮重置表单时,会触发reset 事件
    1. 在 JavaScript 中,以编程方式调用reset()方法也可以重置表单。(以调用 reset()方法的形式重置表单时,不会触发 reset 事件)

    (3) 表单字段

    1. 可以像访问页面中的其他元素一样,使用原生 DOM 方法访问表单元素。
    2. 每个表单都有elements 属性,该属性是表单中所有表单元素(字段)的集合。
    3. elements 集合是一个有序列表, 其中包含着表单中的所有字段,例如<input>、<textarea>、<button>和<fieldset>。每个表单字段在 elements 集合中的顺序,与它们出现在标记中的顺序相同,可以按照位置name 特性来访问它 们。
    var form = document.getElementById("form1");
    //取得表单中的第一个字段
    var field1 = form.elements[0];
    //取得名为"textbox1"的字段
    var field2 = form.elements["textbox1"];
    //取得表单中包含的字段的数量
    var fieldCount = form.elements.length;
    
    1. 如果有多个表单控件都在使用一个 name(如单选按钮),那么就会返回以该 name 命名的一个NodeList
    <form method="post" id="myForm">
        <ul>
            <li><input type="radio" name="color" value="red">Red</li>
            <li><input type="radio" name="color" value="green">Green</li>
            <li><input type="radio" name="color" value="blue">Blue</li>
         </ul>
    </form>
    
    var form = document.getElementById("myForm");
    var colorFields = form.elements["color"];
    alert(colorFields.length);  //3
    var firstColorField = colorFields[0];
    var firstFormField = form.elements[0];
    alert(firstColorField === firstFormField);//true
    
    *共有的表单字段属性

    表单字段共有的 属性如下:

    (1) disabled:布尔值,表示当前字段是否被禁用。
    (2) form:指向当前字段所属表单的指针;只读。
    (3) name:当前字段的名称。
    (4) readOnly:布尔值,表示当前字段是否只读。
    (5) tabIndex:表示当前字段的切换(tab)序号。
    (6) type:当前字段的类型,如"checkbox"、"radio",等等。
    (7) value:当前字段将被提交给服务器的值。对文件字段来说,这个属性是只读的,包含着文件在计算机中的路径。

    除了 form 属性之外,可以通过 JavaScript 动态修改其他任何属性。

    var form = document.getElementById("myForm");
    var field = form.elements[0];
    //修改 value 属性
    field.value = "Another value";
    //检查 form 属性的值 
    alert(field.form === form);//true
    //把焦点设置到当前字段 
    field.focus();
    //禁用当前字段
     field.disabled = true;
    //修改 type 属性(不推荐,但对<input>来说是可行的)
    field.type = "checkbox";
    

    监听 submit 事件,并在该事件 发生时禁用提交按钮避免重复提交表单。

    //避免多次提交表单
    EventUtil.addHandler(form, "submit", function(event){
        event = EventUtil.getEvent(event);
        var target = EventUtil.getTarget(event);
        //取得提交按钮
        var btn = target.elements["submit-btn"];
        //禁用它
        btn.disabled = true;
    });
    

    (1) 除了<fieldset>之外,所有表单字段都有type 属性。对于<input>元素,这个值等于 HTML 特 性 type 的值。对于其他元素,这个 type 属性的值如下表所列。


    (2) <input>和<button>元素的 type 属性是可以动态修改的,而<select>元素的 type 属性 则是只读的。
    *共有的表单字段方法

    每个表单字段都有两个方法:focus()blur()
    1.focus()方法用于将浏览器的焦点设置 到表单字段,即激活表单字段,使其可以响应键盘事件。

    EventUtil.addHandler(window, "load", function(event){ 9 document.forms[0].elements[0].focus();
    });
    

    如果第一个表单字段是一个<input>元素,且其 type 特性的值为"hidden",那么 以上代码会导致错误。另外,如果使用 CSS 的 display 和 visibility 属性隐藏了该字段,同样也会 导致错误。

    HTML5 为表单字段新增了一个 autofocus 属性。在支持这个属性的浏览器中,只要设置这个属性, 不用 JavaScript 就能自动把焦点移动到相应字段。

    1. blur()方法,它的作用是从元素中移走焦点。

    *共有的表单字段事件

    (1) blur:当前字段失去焦点时触发。
    (2) change:对于<input>和<textarea>元素,在它们失去焦点且 value 值改变时触发;对于<select>元素,在其选项改变时触发。 (3) focus:当前字段获得焦点时触发。

     var textbox = document.forms[0].elements[0];
     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 = "";
        }
     });
    

    2. 文本框脚本

    在 HTML 中,有两种方式来表现文本框:一种是使用<input>元素的单行文本框,另一种是使用 <textarea>的多行文本框。

    • <input>元素的 type 特性设置为"text"。
      size 特性可以指 定文本框中能够显示的字符数。
      value 特性可以设置文本框的初始值。
      maxlength 特性则用于指定文本框可以接受的最大字符数。
    //创建一个文本框,让它能够显示 25 个字符,但输入不能 超过 50 个字符
    <input type="text" size="25" maxlength="50" value="initial value">
    
    • <textarea>元素则始终会呈现为一个多行文本框。
      rows 特性指定的是文本框的字符行数。
      cols 特性指定的是文本框的字符列数。
      <textarea>的初始值必须要放在<textarea>和</textarea>之间。
    <textarea rows="25" cols="5">initial value</textarea>
    
    • 这两种文本框都会将用户输入的内容保存在 value 属性中。可以通过这个属性读取和设置文本框的值。

    (1) 选择文本

    select()方法这个方法用于选择文本框中的所有文本。

    在文本框获得焦点时选择其所有文本,这样做可以让用户不必一个一个地删除文本。

    EventUtil.addHandler(textbox, "focus", function(event){
        event = EventUtil.getEvent(event);
        var target = EventUtil.getTarget(event);
        target.select();
    });
    
    * 选择(select)事件

    在选择了文本框中的文本时,就会触发 select 事件。

    (1) 在 IE9+、Opera、Firefox、Chrome 和 Safari 中,只有用户选择了文本(而且要释放鼠标),才会触发 select 事件。
    (2) 在 IE8 及更早版本中,只要用户选择了一个字母(不必释放鼠标),就会触发 select 事件。
    (3) 在调用 select()方法时也会触发 select 事件。

    * 取得选择的文本
    1. selectionStartselectionEnd,这两个属性中保存的是基于 0 的数值,表示所选择 文本的范围(即文本选区开头和结尾的偏移量)。

    要取得用户在文本框中选择的文本,可以使用 如下代码:

    function getSelectedText(textbox){
            return textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
    }
    
    1. IE8 及更早的版本中有一个 document.selection 对象,其中保存着用户在整个文档范围内选择的文本信息;
    function getSelectedText(textbox){
            if (typeof textbox.selectionStart == "number"){   
                    return textbox.value.substring(textbox.selectionStart,textbox.selectionEnd);
             } else if (document.selection){
                    return document.selection.createRange().text;
            }
    }
    
    * 选择部分文本
    1. setSelectionRange()方法,这个方法接收两个参数:要选择的第一个字符的索引和要选择的最后一个字符之后的字符的索引。
    textbox.value = "Hello world!"
    //选择所有文本
    textbox.setSelectionRange(0, textbox.value.length); //"Hello world!"
    //选择前 3 个字符
     textbox.setSelectionRange(0, 3); //"Hel"
    //选择第4到第6个字符 
    textbox.setSelectionRange(4, 7); //"o w"
    
    1. IE8 及更早版本支持使用范围选择部分文本。

    (1) 要选择文本框中的部分文本,必须 首先使用 IE 在所有文本框上提供的 createTextRange()方法创建一个范围,并将其放在恰当的位置 上。
    (2)然后,再使用 moveStart()和 moveEnd()这两个范围方法将范围移动到位。
    (3)不过,在调用这两个 方法以前,还必须使用 collapse()将范围折叠到文本框的开始位置。此时,moveStart()将范围的起 点和终点移动到了相同的位置,只要再给 moveEnd()传入要选择的字符总数即可。
    (4)最后一步,就是使 用范围的 select()方法选择文本。

    textbox.value = "Hello world!";
     var range = textbox.createTextRange();
    //选择所有文本
    range.collapse(true);
    range.moveStart("character", 0);
    range.moveEnd("character", textbox.value.length); //"Hello world!" 
    range.select();
    
    //选择前 3 个字符
     range.collapse(true);
     range.moveStart("character", 0); range.moveEnd("character", 3);
     range.select();//"Hel"
    
    //选择第4到第6个字符
    range.collapse(true); 
    range.moveStart("character", 4); 
    range.moveEnd("character", 3); 
    range.select();//"o w"
    
    1. 实现跨浏览器编程
    function selectText(textbox, startIndex, stopIndex){
        if (textbox.setSelectionRange){
            textbox.setSelectionRange(startIndex, stopIndex);
        } else if (textbox.createTextRange){
            var range = textbox.createTextRange();
            range.collapse(true);
            range.moveStart("character", startIndex);
            range.moveEnd("character", stopIndex - startIndex);
            range.select();
        }
            textbox.focus();
    }
    
    

    想在文本框中看到文本被选择的效果,必须让文本框获得焦点。

    (2) 过滤输入

    *屏蔽字符

    响应向文本框中插入字符操作的是keypress 事件。因此,可以通过阻止这个事件的默认行为来屏蔽此类字符。

    下列代码只允许用户输入数值:

    EventUtil.addHandler(textbox, "keypress", function(event){          
            event = EventUtil.getEvent(event);
            var target = EventUtil.getTarget(event);
            var charCode = EventUtil.getCharCode(event);
            if (!/\d/.test(String.fromCharCode(charCode))){
                    EventUtil.preventDefault(event);
            }
    });
    

    理论上只应该在用户按下字符键时才触发 keypress 事件,但有些浏览器也会对其他键触发此 事件。Firefox 和 Safari(3.1 版本以前)会对向上键、向下键、退格键和删除键触发 keypress 事件;在 Firefox 中,所 有由非字符键触发的 keypress 事件对应的字符编码为 0,而在 Safari 3 以前的版本中,对应的字符编 码全部为 8。为了让代码更通用,只要不屏蔽那些字符编码小于 10 的键即可

    EventUtil.addHandler(textbox, "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){
                EventUtil.preventDefault(event);
            }
    });
    

    最后还要添加一 个检测条件,以确保用户没有按下 Ctrl 键。

    EventUtil.addHandler(textbox, "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);
            }
    });
    
    *操作剪贴板

    6 个剪贴板事件:

    (1) beforecopy:在发生复制操作前触发。
    (2) copy:在发生复制操作时触发。
    (3) beforecut:在发生剪切操作前触发。
    (4) cut:在发生剪切操作时触发。
    (5) beforepaste:在发生粘贴操作前触发。
    (6) paste:在发生粘贴操作时触发。

    clipboardData 对象:访问剪贴板中的数据。

    1. 在 IE 中,这个对象是 window 对象的 属性;而在 Firefox 4+、Safari 和 Chrome 中,这个对象是相应 event 对象的属性。
    2. clipboardData 对象有三个方法:getData()、setData()和 clearData()。
      (1) getData()用于从剪贴板中取得数据,它接受一个参数,即要取得的数据的格式。在 IE 中,有两种数据格式:"text" 和"URL"。在 Firefox、Safari 和 Chrome 中,这个参数是一种 MIME 类型;不过,可以用"text"代表 "text/plain"。
      (2)setData()方法的第一个参数也是数据类型,第二个参数是要放在剪贴板中的文本。对于 第一个参数,IE 照样支持"text"和"URL",而 Safari 和 Chrome 仍然只支持 MIME 类型。成功将文本放到剪贴板中后,都会返回 true;否则,返回 false。
    var EventUtil = {
             //省略的代码
            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);
                 }
             },
            //省略的代码 
    };
    

    如果一个文本框只接受数值,在 paste 事件中,可以确定剪贴板中的值是否有效,如果无效,就可以像下面示例中那样,取消默认的行为。

    EventUtil.addHandler(textbox, "paste", function(event){
        event = EventUtil.getEvent(event);
        var text = EventUtil.getClipboardText(event);
        if (!/^\d*$/.test(text)){
            EventUtil.preventDefault(event);
        }
    });
    

    (3) 自动切换焦点

    
        <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">
    
    (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("txtTel1");
        var textbox2 = document.getElementById("txtTel2");
        var textbox3 = document.getElementById("txtTel3");
        EventUtil.addHandler(textbox1, "keyup", tabForward);
        EventUtil.addHandler(textbox2, "keyup", tabForward);
        EventUtil.addHandler(textbox3, "keyup", tabForward);
    })();
    

    (4) HTML5 约束验证API

    * 必填字段

    required 属性: 任何标注有 required 的字段,在提交表单时都不能空着。这个属性适用于<input>、<textarea> 和<select>字段。

    <input type="text" name="username" required>
    
    *其他输入类型

    HTML5 为<input>元素的 type 属性又增加了几个值。这些新的类型不仅能反映数据类型的信息, 而且还能提供一些默认的验证功能。其中,"email""url"是两个得到支持最多的类型,各浏览器也都为它们增加了定制的验证机制。

    <input type="email" name ="email">
    <input type="url" name="homepage">
    
    *数值范围

    这几个元素都要求填写某种基于数字的值:
    "number"、"range"、"datetime"、"datetimelocal"、"date"、"month"、"week"、有"time"

    所有这些数值类型的输入元素,可以指定 min 属性(最小的可能值)、max 属性(最大的可能值) 和 step 属性(从 min 到 max 的两个刻度间的差值)。

    <input type="number" min="0" max="100" step="5" name="count">
    

    stepUp() 和 stepDown()都接收一个可选的参数:要在当前值基础上加上或减去的数值。(默认是加或减 1。)

    input.stepUp(); //加1
     input.stepUp(5);//加5
     input.stepDown(); //减1
    input.stepDown(10);//减5
    
    *输入模式

    HTML5为文本字段新增了pattern属性。这个属性的值是一个正则表达式,用于匹配文本框中的 值。

    <input type="text" pattern="\d+" name="count">
    
    *检测有效性

    checkValidity()方法可以检测表单中的某个字段是否有效。

    1. 所有表单字段都有个方法,如 果字段的值有效,这个方法返回 true,否则返回 false。
    2. 必填字段中如果没有值就是无效的,而字段中的值与 pattern 属性不匹 配也是无效的。
    if(document.forms[0].checkValidity()){ 
    //表单有效,继续
    } else { 
    //表单无效
    }
    

    validity 属性则会告诉你为什么字 段有效或无效。

    (1) customError :如果设置了 setCustomValidity(),则为 true,否则返回 false。
    (2) patternMismatch:如果值与指定的 pattern 属性不匹配,返回 true。
    (3) rangeOverflow:如果值比 max 值大,返回 true。
    (4) rangeUnderflow:如果值比 min 值小,返回 true。
    (5) stepMisMatch:如果 min 和 max 之间的步长值不合理,返回 true。
    (6) tooLong:如果值的长度超过了 maxlength 属性指定的长度,返回 true。有的浏览器(如 Firefox 4)会自动约束字符数量,因此这个值可能永远都返回 false。
    (7) typeMismatch:如果值不是"mail"或"url"要求的格式,返回 true。
    (8) valid:如果这里的其他属性都是 false,返回 true。checkValidity()也要求相同的值。
    (9) valueMissing:如果标注为 required 的字段中没有值,返回 true。

    if (input.validity && !input.validity.valid){
            if (input.validity.valueMissing){
                alert("Please specify a value.")
            } else if (input.validity.typeMismatch){
                alert("Please enter an email address.");
            } else {
                alert("Value is invalid.");
            }
    }
    
    *禁用验证

    novalidate 属性,可以告诉表单不进行验证。

    <form method="post" action="signup.php" novalidate> <!--这里插入表单元素-->
    </form>
    

    3. 选择框脚本

    选择框是通过<select><option>元素创建的。

    • HTMLSelectElement 类型还提供了下列属性和方法:

    (1) add(newOption, relOption):向控件中插入新<option>元素,其位置在相关项(relOption) 之前。
    (2) multiple:布尔值,表示是否允许多项选择;等价于 HTML 中的 multiple 特性。
    (3) options:控件中所有<option>元素的 HTMLCollection。
    (4) remove(index):移除给定位置的选项。
    (5) selectedIndex:基于 0 的选中项的索引,如果没有选中项,则值为-1。对于支持多选的控件,只保存选中项中第一项的索引。
    (6) size:选择框中可见的行数;等价于 HTML 中的 size 特性。

    • 选择框的 type 属性不是"select-one",就是"select-multiple",这取决于 HTML 代码中有 没有 multiple 特性。
    • 选择框的 value 属性由当前选中项决定,相应规则如下:

    (1) 如果没有选中的项,则选择框的 value 属性保存空字符串。
    (2) 如果有一个选中项,而且该项的 value 特性已经在 HTML 中指定,则选择框的 value 属性等于选中项的 value 特性。即使 value 特性的值是空字符串,也同样遵循此条规则。
    (3) 如果有一个选中项,但该项的 value 特性在 HTML 中未指定,则选择框的 value 属性等于该项的文本。
    (4) 如果有多个选中项,则选择框的 value 属性将依据前两条规则取得第一个选中项的值。

    • 在 DOM 中,每个<option>元素都有一个 HTMLOptionElement 对象表示。为便于访问数据, HTMLOptionElement 对象添加了下列属性:

    (1) index:当前选项在 options 集合中的索引。
    (2) label:当前选项的标签;等价于 HTML 中的 label 特性。
    (3) selected:布尔值,表示当前选项是否被选中。将这个属性设置为 true 可以选中当前选项。
    (4) text:选项的文本。
    (5) value:选项的值(等价于 HTML 中的 value 特性)。

    (1) 选择选项

    1. 对于只允许选择一项的选择框,访问选中项的最简单方式,就是使用选择框的 selectedIndex 属性
    var selectedIndex = selectbox.selectedIndex;
        var selectedOption = selectbox.options[selectedIndex];
        alert("Selected index: " + selectedIndex + "\nSelected text: " +
              selectedOption.text + "\nSelected value: " + selectedOption.value);
    

    对于可以选择多项的选择框,selectedfIndex 属性就好像只允许选择一项一样。设置 selectedIndex 会导致取消以前的所有选项并选择指定的那一项,而读取 selectedIndex 则只会返回选中项中第一项的索引值。

    1. 另一种选择选项的方式,就是取得对某一项的引用,然后将其 selected 属性设置为 true。
    selectbox.options[0].selected = true;
    

    在允许多选的选择框中设置选项的 selected 属性,不会取消对其他选中项 的选择。

    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;
    }
    
    
    var selectbox = document.getElementById("selLocation");
    var selectedOptions = getSelectedOptions(selectbox);
    var message = "";
    for (var i=0, len=selectedOptions.length; i < len; i++){
        message += "Selected index: " + selectedOptions[i].index +
        "\nSelected text: " + selectedOptions[i].text +
        "\nSelected value: " + selectedOptions[i].value + "\n\n";
    }
    alert(message);
    

    (2) 添加选项

    1. 第一种方 式就是使用如下所示的 DOM 方法。
    var newOption = document.createElement("option"); newOption.appendChild(document.createTextNode("Option text"));
    newOption.setAttribute("value", "Option value");
    selectbox.appendChild(newOption);
    
    1. 第二种方式是使用 Option 构造函数来创建新选项,Option 构造函数接受两个参数:文本(text)和值(value);第二个参数可选。
    var newOption = new Option("Option text", "Option value");
    selectbox.appendChild(newOption); //在 IE8 及之前版本中有问题
    
    1. add()方法接受两个参数:要添加 的新选项和将位于新选项之后的选项。如果想在列表的最后添加一个选项,应该将第二个参数设置为 null。兼容 DOM 的浏览器要求必须指定第二个参数,第二个参数传入 undefined,就可以在所有浏览器中都将新选项插入到列 表最后了。
    var newOption = new Option("Option text", "Option value"); 
    selectbox.add(newOption, undefined); //最佳方案
    

    (3) 移除选项

    1. 使用 DOM 的 removeChild()方法,其传入要移除的选项。
    selectbox.removeChild(selectbox.options[0]); //移除第一个选项
    
    1. remove()方法,这个方法接受一个参数,即要移除选项的索引。
    selectbox.remove(0); //移除第一个选项
    
    1. 将相应选项设置为 null。
    selectbox.options[0] = null; //移除第一个选项
    

    要清除选择框中所有的项:

    function clearSelectbox(selectbox){
            for(var i=0, len=selectbox.options.length; i < len; i++){
                selectbox.remove(i);
            }
    }
    

    (4) 移动和重排选项

    1. 使用 DOM 的 appendChild()方法,就可以将第一个选择框中的选项直接移动到第二个选 择框中。我们知道,如果为 appendChild()方法传入一个文档中已有的元素,那么就会先从该元素的 父节点中移除它,再把它添加到指定的位置。
    var selectbox1 = document.getElementById("selLocations1");
    var selectbox2 = document.getElementById("selLocations2");
    selectbox2.appendChild(selectbox1.options[0]);
    
    1. 要在选择框中向前移动一个选项的位置,可以使用以下代码:
    var optionToMove = selectbox.options[1];
    selectbox.insertBefore(optionToMove, selectbox.options[optionToMove.index-1]);
    
    1. 下列代码将选择框中的选项向后移动一 个位置:
    var optionToMove = selectbox.options[1];
    selectbox.insertBefore(optionToMove, selectbox.options[optionToMove.index+2]);
    

    4. 表单序列化

    在表单提交期间,浏览器将数据发送给服务器:

    (1) 对表单字段的名称和值进行 URL 编码,使用和号(&)分隔。
    (2) 不发送禁用的表单字段。
    (3) 只发送勾选的复选框和单选按钮。
    (4) 不发送 type 为"reset"和"button"的按钮。
    (5) 多选选择框中的每个选中的值单独一个条目。
    (6) 在单击提交按钮提交表单的情况下,也会发送提交按钮;否则,不发送提交按钮。也包括 type为"image"的<input>元素。
    (7) <select>元素的值,就是选中的<option>元素的 value 特性的值。如果<option>元素没有value 特性,则是<option>元素的文本值。

    表单序列化的代码:
    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(field.value));
                          }    
                  }
          }  
          return parts.join("&");
    }                  
    

    5.富文本编辑

    在页面中嵌入一个包含空 HTML 页面的iframe。通过设置 designMode 属性,这个空白 的 HTML 页面可以被编辑,而编辑对象则是该页面<body>元素的 HTML 代码。designMode 属性有两 个可能的值:"off"(默认值)和"on"。在设置为"on"时,整个文档都会变得可以编辑(显示插入符 号),然后就可以像使用字处理软件一样,通过键盘将文本内容加粗、变成斜体。

    <!DOCTYPE html>
        <html>
            <head>
                <title>Blank Page for Rich Text Editing</title>
            </head>
            <body>
            </body>
    </html>
    
    <iframe name="richedit" style="height:100px;width:100px;" src="blank.htm"></iframe>
        <script type="text/javascript">
        EventUtil.addHandler(window, "load", function(){
            frames["richedit"].document.designMode = "on";
        });
    </script>
    

    (1) 使用contenteditable属性

    1. 可以把 contenteditable 属性应用给页面中的任何元素,然后用户立即就可以编辑该元素。 这种方法之所以受到欢迎,是因为它不需要 iframe、空白页和 JavaScript,只要为元素设置 contenteditable 属性即可。
    <div class="editable" id="richedit" contenteditable></div>
    
    1. contenteditable 属性有三个可能的值:"true"表示打开、"false"表示关闭,"inherit"表示 从父元素那里继承(因为可以在 contenteditable 元素中创建或删除元素)。
    var div = document.getElementById("richedit");
    div.contentEditable = "true";
    

    (2) 操作富文本

    1. document.execCommand()这个方法可以对文档执 行预定义的命令,可以为 document.execCommand()方法传递 3 个参数: 要执行的命令名称表示浏览器是否应该为当前命令提供用户界面的一个布尔值执行命令必须的一个 值(如果不需要值,则传递 null)。为了确保跨浏览器的兼容性,第二个参数应该始终设置为 false, 因为 Firefox 会在该参数为 true 时抛出错误。

    使用这些命令来修改富文本区域的外观:

    //转换粗体文本
    frames["richedit"].document.execCommand("bold", false, null);
    //转换斜体文本
    frames["richedit"].document.execCommand("italic", false, null);
    //创建指向 www.wrox.com 的链接
    frames["richedit"].document.execCommand("createlink", false,"http://www.wrox.com");
    //格式化为1级标题
    frames["richedit"].document.execCommand("formatblock", false, "<h1>");
    

    同样的方法也适用于页面中 contenteditable 属性为"true"的区块,只要把对框架的引用替换 成当前窗口的 document 对象即可。

    //转换粗体文本
    document.execCommand("bold", false, null);
    //转换斜体文本
    document.execCommand("italic", false, null);
    //创建指向 www.wrox.com 的链接
    document.execCommand("createlink", false,"http://www.wrox.com");
    
    1. queryCommandEnabled()可以用它来检 测是否可以针对当前选择的文本,或者当前插入字符所在位置执行某个命令。这个方法接收一个参数,即要 检测的命令。如果当前编辑区域允许执行传入的命令,这个方法返回 true,否则返回 false。
    var result = frames["richedit"].document.queryCommandEnabled("bold");
    
    1. queryCommandState()方法用于确定是否已将指定命令应用到了选择的文本。例如,要确 定当前选择的文本是否已经转换成了粗体,可以使用如下代码
    var isBold = frames["richedit"].document.queryCommandState("bold");
    
    1. queryCommandValue(),用于取得执行命令时传入的值(即前面例子中传给 document.execCommand()的第三个参数)。例如,在对一段文本应用"fontsize"命令时如果传入了 7,那么下面的代码就会返回"7":
    var fontSize = frames["richedit"].document.queryCommandValue("fontsize");
    

    (3) 富文本选区

    在富文本编辑器中,使用框架(iframe)的getSelection()方法,可以确定实际选择的文本。 这个方法是 window 对象和 document 对象的属性,调用它会返回一个表示当前选择文本的 Selection 对象。

    (4) 表单与富文本

    富文本编辑器中的 HTML 不会被自动提交给服务器,而需要我们手工来提取并提交 HTML。为此,通常可以添加一个隐藏的表单字段,让它的值等于从 iframe 中提取出的 HTML。具体 来说,就是在提交表单之前,从 iframe 中提取出 HTML,并将其插入到隐藏的字段中。

    EventUtil.addHandler(form,"submit",function(event) {
            event = EventUtil.getEvent(event); 
            var target = EventUtil.getTarget(event);
             target.elements["comments"].value = frames["richedit"].document.body.innerHTML; 
    });
    

    相关文章

      网友评论

        本文标题:JavaScript 高级程序设计(第14章 表单脚本)

        本文链接:https://www.haomeiwen.com/subject/ntuzbftx.html