乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      prototype 源碼解讀的第三部分 - form.js

       douli 2005-07-23

      prototype 源碼解讀的第三部分 - form.js

      form.js 中主要定義了一些靜態(tài)工具類,比如 Form.serialize 獲取表單的所有元素的值并組合成以 & 相連的querystring,這顯然用于組合XmlHttp 提交數(shù)據(jù)。

      另外值得關(guān)注的是 Form.Observer,我們可以學(xué)習(xí)到 javascript 如何應(yīng)用設(shè)計模式。

      form.js

       

      /**
       * 針對 頁面元素對象 的工具類,提供一些簡單靜態(tài)方法
       */
      var Field = {
        /**
         * 清除參數(shù)引用對象的值
         */
        clear: function() {
          for (var i = 0; i < arguments.length; i++)
            $(arguments[i]).value = ‘‘;
        },

        /**
         * 使參數(shù)引用對象獲取焦點
         */
        focus: function(element) {
          $(element).focus();
        },
       
        /**
         * 判斷參數(shù)引用對象值是否為空,如為空,返回false, 反之true
         */
        present: function() {
          for (var i = 0; i < arguments.length; i++)
            if ($(arguments[i]).value == ‘‘) return false;
          return true;
        },
       
        /**
         * 使選中參數(shù)引用對象
         */
        select: function(element) {
          $(element).select();
        },

        /**
         * 使參數(shù)引用對象處于可編輯狀態(tài)
         */
        activate: function(element) {
          $(element).focus();
          $(element).select();
        }
      }

      /*--------------------------------------------------------------------------*/

      /**
       * 表單工具類
       */
      var Form = {
        /**
         * 將表單元素序列化后的值組合成 QueryString 的形式
         */
        serialize: function(form) {
          var elements = Form.getElements($(form));
          var queryComponents = new Array();
         
          for (var i = 0; i < elements.length; i++) {
            var queryComponent = Form.Element.serialize(elements[i]);
            if (queryComponent)
              queryComponents.push(queryComponent);
          }
         
          return queryComponents.join(‘&‘);
        },
       
        /**
         * 得到表單的所有元素對象
         */
        getElements: function(form) {
          form = $(form);
          var elements = new Array();

          for (tagName in Form.Element.Serializers) {
            var tagElements = form.getElementsByTagName(tagName);
            for (var j = 0; j < tagElements.length; j++)
              elements.push(tagElements[j]);
          }
          return elements;
        },
       
        /**
         * 將指定表單的元素置于不可用狀態(tài)
         */
        disable: function(form) {
          var elements = Form.getElements(form);
          for (var i = 0; i < elements.length; i++) {
            var element = elements[i];
            element.blur();
            element.disable = ‘true‘;
          }
        },

        /**
         * 使表單的第一個非 hidden 類型而且處于可用狀態(tài)的元素獲得焦點
         */
        focusFirstElement: function(form) {
          form = $(form);
          var elements = Form.getElements(form);
          for (var i = 0; i < elements.length; i++) {
            var element = elements[i];
            if (element.type != ‘hidden‘ && !element.disabled) {
              Field.activate(element);
              break;
            }
          }
        },

        /*
         * 重置表單
         */
        reset: function(form) {
          $(form).reset();
        }
      }

      /**
       * 表單元素工具類
       */
      Form.Element = {
        /**
         * 返回表單元素的值先序列化再進行 URL 編碼后的值
         */
        serialize: function(element) {
          element = $(element);
          var method = element.tagName.toLowerCase();
          var parameter = Form.Element.Serializers[method](element);
         
          if (parameter)
            return encodeURIComponent(parameter[0]) + ‘=‘ +
              encodeURIComponent(parameter[1]);                  
        },
       
        /**
         *  返回表單元素序列化后的值
         */
        getValue: function(element) {
          element = $(element);
          var method = element.tagName.toLowerCase();
          var parameter = Form.Element.Serializers[method](element);
         
          if (parameter)
            return parameter[1];
        }
      }

      /**
       * prototype 的所謂序列化其實就是將表單的名字和值組合成一個數(shù)組
       */
      Form.Element.Serializers = {
        input: function(element) {
          switch (element.type.toLowerCase()) {
            case ‘hidden‘:
            case ‘password‘:
            case ‘text‘:
              return Form.Element.Serializers.textarea(element);
            case ‘checkbox‘: 
            case ‘radio‘:
              return Form.Element.Serializers.inputSelector(element);
          }
          return false;
        },
       
        inputSelector: function(element) {
          if (element.checked)
            return [element.name, element.value];
        },

        textarea: function(element) {
          return [element.name, element.value];
        },

        /**
         * 看樣子,也不支持多選框(select-multiple)
         */
        select: function(element) {
          var index = element.selectedIndex;
          var value = element.options[index].value || element.options[index].text;
          return [element.name, (index >= 0) ? value : ‘‘];
        }
      }

      /*--------------------------------------------------------------------------*/

      /**
       * Form.Element.getValue 也許會經(jīng)常用到,所以做了一個快捷引用
       */
      var $F = Form.Element.getValue;

      /*--------------------------------------------------------------------------*/

      /**
       * Abstract.TimedObserver 也沒有用 Class.create() 來創(chuàng)建,和Ajax.Base 意圖應(yīng)該一樣
       * Abstract.TimedObserver 顧名思義,是套用Observer設(shè)計模式來跟蹤指定表單元素,
       * 當(dāng)表單元素的值發(fā)生變化的時候,就執(zhí)行回調(diào)函數(shù)
       *
       * 我想 Observer 與注冊onchange事件相似,不同點在于 onchange 事件是在元素失去焦點的時候才激發(fā)。
       * 同樣的與 onpropertychange 事件也相似,不過它只關(guān)注表單元素的值的變化,而且提供timeout的控制。
       *
       * 除此之外,Observer 的好處大概就在與更面向?qū)ο螅硗饪梢詣討B(tài)的更換回調(diào)函數(shù),這就比注冊事件要靈活一些。
       * Observer 應(yīng)該可以勝任動態(tài)數(shù)據(jù)校驗,或者多個關(guān)聯(lián)下拉選項列表的連動等等
       *
       */
      Abstract.TimedObserver = function() {}

      /**
       * 這個設(shè)計和 PeriodicalExecuter 一樣,bind 方法是實現(xiàn)的核心
       */
      Abstract.TimedObserver.prototype = {
        initialize: function(element, frequency, callback) {
          this.frequency = frequency;
          this.element   = $(element);
          this.callback  = callback;
         
          this.lastValue = this.getValue();
          this.registerCallback();
        },
       
        registerCallback: function() {
          setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000);
        },
       
        onTimerEvent: function() {
          var value = this.getValue();
          if (this.lastValue != value) {
            this.callback(this.element, value);
            this.lastValue = value;
          }
         
          this.registerCallback();
        }
      }

      /**
       * Form.Element.Observer 和 Form.Observer 其實是一樣的
       * 注意 Form.Observer 并不是用來跟蹤整個表單的,我想大概只是為了減少書寫(這是Ruby的一個設(shè)計原則)
       */
      Form.Element.Observer = Class.create();
      Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({
        getValue: function() {
          return Form.Element.getValue(this.element);
        }
      });

      Form.Observer = Class.create();
      Form.Observer.prototype = (new Abstract.TimedObserver()).extend({
        getValue: function() {
          return Form.serialize(this.element);
        }
      });


      此日記TrackBack地址: http://www./trackback.do?log_id=866

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多