JavaScript 高級程序設計(第14章 表單腳本)

第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; 
});
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容