1. 程式人生 > >高程3總結#第14章表單指令碼

高程3總結#第14章表單指令碼

表單指令碼

表單的基礎知識

  • HTMLFormElement有自己獨特的屬性和方法

    • acceptCharset,伺服器能夠處理的字符集,等價於HTML中的accept-charset特性
    • action,接受請求的URL,等價於HTML中的action特性
    • elements,表單中所有控制元件的集合
    • enctype,請求的編碼型別,等價於HTML中的enctype特性
    • length,表單中控制元件的數量
    • method,要傳送的HTTP請求型別,通常是"get"或"post",等價於HTML的method特性
    • name,表單的名稱,等價於HTML的name特性
    • reset(),將所有表單域重置為預設值
    • submit(),提交表單
    • target(),用於傳送請求和接收響應的視窗名稱,等級與HTML的target特性

提交表單

  • 使用者單擊提交按鈕或者影象按鈕時,就會提交表單,使用<input>或<button>都可以自定義提交按鈕,只要將type特性的值設定為"submit"即可

    <!--通用提交按鈕-->
    <input type="submit" value="Submit Form">
    <!--自定義提交按鈕-->
    <button type="submit">Submit Form</button>
    <!--影象按鈕-->
    <input type="image" src="graphic.gif">
  • 阻止表單提交程式碼

    var form=document.getElelemtById("myForm");
    EventUtil.addHandler(form,"submit",function(event){
      //取得事件物件
      event=EventUtil.getEvent(event);
      //阻止預設事件
      EventUtil.preventDefault(event);
    })
  • 以程式設計方式提交表單,不會觸發submit事件,因此呼叫方法之前要先驗證表單資料

    var form=document.getElementById("muForm");
    //提交表單
    form.submit();
  • 提交表單時,可能出現最大的問題就是重複提交表單,在第一次提交表單之後,如果長時間沒有反應,使用者可能會反覆單擊提交按鈕。解決辦法兩個,第一次提交之後就禁用提交按鈕,或者利用onsubmit事件處理程式取消後續的表單提交操作

重置表單

  • 在使用者單擊重置按鈕時,表單會被重置,使用type特性值為reset的<input>或<button>都可以建立重置按鈕

    <!-- 通用重置按鈕 -->
    <input type="reset" value="Reset Form">
    <!-- 自定義重置按鈕 -->
    <button type="reset">Reset Form</button>
  • 阻止重置表單的程式碼

    var form = document.getElementById("myForm");
    EventUtil.addHandler(form, "reset", function(event){
      //取得事件物件
      event = EventUtil.getEvent(event);
      //阻止表單重置
      EventUtil.preventDefault(event);
    });
  • 可以通過JavaScript來重置表單

    var form=document.getElementById("myForm");
    //重置表單
    form.reset();
  • 與呼叫submit()方法不同,呼叫submit方法會像單擊按鈕一樣觸發reset事件

表單欄位

  • 表單欄位公有的屬性

    • disabled,布林值,表示當前欄位是否被禁用
    • form,指向當前欄位所屬表單的指標。只讀
    • name,當前欄位的名稱
    • readOnly,布林值,表示當前欄位是否只讀
    • tabIndex,表示當前欄位的切換序號
    • type,當前欄位型別,如CheckBox
    • value當前欄位將被提交給伺服器的值圖片描述
  • 公有的表單欄位方法

    • 每個表單都有兩個方法,focus()和blur(),其中focus()方法用於將瀏覽器的焦點設定到表單欄位,即啟用欄位,使其可以響應鍵盤事件。在呼叫blur方法時,並不會把焦點轉移到某個特定的元素上,僅僅是將焦點從呼叫這個方法的元素上移走
  • 公有的表單欄位事件

    • blur,當前欄位失去焦點時觸發
    • change,對於input和textarea元素,在失去焦點且value值改變時觸發,對於select元素,在選擇選項時觸發
    • 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 = "";
      }
    })

文字框指令碼

  • 兩種方式來表示文字框,input和textarea

選擇文字

  • 兩種文字框都支援select()方法,與select()方法對應的是一個select事件,選擇文字框中的文字時,就會觸發select事件
  • 新增兩個屬性:selectionStart和selectionEnd,儲存的是基於0的數值,表示選擇文字的範圍
  • 所有文字框都有一個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"

過濾輸入

  • 剪下板事件

    • beforecopy,在發生複製操作前觸發
    • copy,在發生複製操作時觸發
    • beforecut,在發生剪下操作前觸發
    • cut,在發生剪下操作時觸發
    • beforepaste,在發生貼上操作前觸發
    • paste,在發生貼上操作時觸發

自動切換焦點

(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);
})();

HTML5約束驗證API

  • 必填欄位

    • 指定required屬性

      <input type="text" name="username" required>
  • 其他輸入型別

    • 新增email和url等型別

      <input type="email" name="email">
      <input type="url" name="homepage">
  • 數值範圍

    • number,range,datetime,datetime-local,date,mouth,week,time等
  • 輸入模式

    • pattern屬性,這個屬性的值是一個正則表示式,用於匹配文字框中的值

      <input type="text" pattern="\d+" name="count">
  • 檢測有效性

    • checkValidty()方法,檢測表單彙總某個欄位是否有效,所有表單欄位都有這個方法,如果欄位有效,返回true,反之返回false

      if (document.forms[0].elements[0].checkValidity()){
      //欄位有效,繼續
      } else {
      //欄位無效
      }
    • customError,如果設定了setCustomValidity,則為true,否則為false
    • patternMismatch,如果值與指定的pattern屬性不匹配,返回true
    • rangeOverflow,如果值比max值大,返回true
    • rangeUnderflow,如果值比min值小,返回true
    • stepMisMatch,如果max和min之間的步長值不合適,返回true
    • tooLong,如果值的長度超過了maxlength屬性指定的長度,返回true
    • typeMismatch,如果值不是mail或url返回的格式,返回true
    • valid,如果這裡的屬性都是false,返回true
    • valueMissing,如果標註為required的欄位中滅有值,返回true
  • 通過設定novalidate屬性,可以告訴表單不進行驗證

    <form method="post" action="signup.php" novalidate>
      <!--這裡插入表單元素-->
    </form>

選擇框指令碼

  • HTMLSelectElement型別提供的屬性和方法

    • add(newOption, relOption),向控制元件中插入新 <option> 元素,其位置在相關項(relOption)之前。
    • multiple,布林值,表示是否允許多項選擇;等價於 HTML 中的 multiple 特性。
    • options,控制元件中所有 <option> 元素的 HTMLCollection 。
    • remove(index),移除給定位置的選項。
    • selectedIndex,基於 0 的選中項的索引,如果沒有選中項,則值為-1。對於支援多選的控制元件,只儲存選中項中第一項的索引。
    • size,選擇框中可見的行數;等價於 HTML 中的 size 特性
  • 選擇框的value屬性由當前選中項決定,相應規則

    • 如果沒有選中的項,則選擇框的 value 屬性儲存空字串。
    • 如果有一個選中項,而且該項的 value 特性已經在 HTML 中指定,則選擇框的 value 屬性等於選中項的 value 特性。即使 value 特性的值是空字串,也同樣遵循此條規則。
    • 如果有一個選中項,但該項的 value 特性在 HTML 中未指定,則選擇框的 value 屬性等於該項的文字。
    • 如果有多個選中項,則選擇框的 value 屬性將依據前兩條規則取得第一個選中項的值。
  • 為了便於訪問資料,HTMLOptionElement物件新增下列屬性

    • index,當前選項在option集合中的索引
    • label,當前選項的標籤,等價於HTML中的label特性
    • selected,布林值,表示當前選項是否被選中,將這個屬性設定為true可以選中當前選項
    • text,選項的文字
    • value,選項的值,等價於HTML中的value特性

選擇選項

  • 對於只允許選擇一項的選擇框,訪問選中項的最簡單方式就是使用選擇框的selectedIndex屬性

    var selectedOption=selectbox.opitons[selectbox,selectedIndex]

新增選項

  • 新增選項的方式有很多,第一種方式就是使用如下所示的DOM方法

    var newOption=document.createElement("option");
    newOption.appendChild(document.createTextNode("Option text"));
    newOption.setAttribute("value","Option value");
    selectbox.appendChild(newOption);
  • 第二種方式是使用Option建構函式來建立新選項

    var newOption=new Option("Option text","Option value");
    selectbox.appendChild(newOption);//在IE8及之前版本中有問題
  • 第三種新增新選項的方式是使用選擇框的add()方法

    var newOption=new Option("Option text","Option value");
    selectbox.add(newOption,undefined);//最佳方案

移除選項

  • removeChild()方法,移除選項

    selectbox.removeChild(selectbox.options[0]);//移除第一個選項
  • remove()方法,移除選項

    selectbox.remove(0);//移除第一個選項
  • 將相應的選項設定為null,移除選項

    selectbox.options[0]=null;//移除第一個選項

表單序列化

  • 瀏覽器將資料傳送給伺服器

    • 對錶單欄位的名稱和值進行URL編碼,使用&符分隔
    • 不傳送禁用的表單欄位
    • 只發送勾選的複選框和單選按鈕
    • 不傳送type為"reset"和"button"的按鈕
    • 多選選擇框中的每個選中的值單獨一個條目
    • 在單擊提交按鈕提交表單的情況下,也會發送提交按鈕,否則不傳送提交按鈕,也包括type為"image"的<input>元素
    • <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("&");
    }

富文字編輯

  • 富文字編輯,WYSIWYG(What You See Is What You Get)所見即所得

使用contenteditable

  • 這個屬性時由IE最早實現的,可以把contenteditable屬性應用給頁面中的任何元素,然後使用者立即就可以編輯該元素。這種方法之所以受到歡迎,是因為它不需要iframe、空白頁和JavaScript,之喲啊哦為元素設定contenteditable屬性即可

    <div class="editable" id="richedit" contentdeitable></div>

操作富文字

  • 與富文字編輯器互動的主要方式就是使用document.execCommand(),這個方法可以對文件執行預定義的命令,而且可以應用大多數格式,可以為document.execCommand()方法傳遞3個引數:要執行的命令名稱、表示瀏覽器是否應該為當前命令提供使用者介面的一個布林值和執行命令必須的一個值,為了確保跨瀏覽器的相容性,第二個引數應該始終設定為false,因為Firefox會在該引數為true時丟擲錯誤圖片描述

富文字選區

  • 每個Selection物件的屬性

    • anchorNode,選取起點所在的節點
    • anchorOffset,在到達選區起點位置之前跳過的anchorNode中的字元數量
    • focusNode,選區終點所在的節點
    • focusOffset,focusNode中包含在選區之內的字元數量
    • isCollapse,布林值,表示選區的起點和終點是否重合
    • rangeCount,選區中包含的DOM範圍的數量
  • 物件的方法提供了更多資訊,支援對選區的操作

    • addRange(range),將指定的 DOM 範圍新增到選區中。
    • collapse(node, offset),將選區摺疊到指定節點中的相應的文字偏移位置。
    • collapseToEnd(),將選區摺疊到終點位置。
    • collapseToStart(),將選區摺疊到起點位置。
    • containsNode(node),確定指定的節點是否包含在選區中。
    • deleteFromDocument(),從文件中刪除選區中的文字,與document.execCommand("delete",false, null) 命令的結果相同。
    • extend(node, offset),通過將 focusNode 和 focusOffset 移動到指定的值來擴充套件選區。
    • getRangeAt(index),返回索引對應的選區中的 DOM 範圍。
    • removeAllRanges(),從選區中移除所有 DOM 範圍。實際上,這樣會移除選區,因為選區中至少要有一個範圍。
    • reomveRange(range),從選區中移除指定的 DOM 範圍。
    • selectAllChildren(node),清除選區並選擇指定節點的所有子節點。
    • toString(),返回選區所包含的文字內容。