Prototype常用函數

2.2.1  $()函數

DOM提供了 document.getElementById方法,可以根據傳入的頁面元素的id返回相應的元素對象。$()函數是 document.getElementById函數的一個簡化寫法,它比DOM中的方法功能更加強大,比如$()函數可以接受多個參數,返回滿足條件的 Array對象。在Prototype中$()函數的實現代碼如例2-1所示。

例2-1  $()函數

function $() {

  var results = [], element;

  for (var i = 0; i < arguments.length; i++) { // 可以傳入多個參數

    element = arguments[i];

    

     // 如果參數的類型是字符串

    if (typeof element == 'string')

      element = document.getElementById(element);

   

    results.push(Element.extend(element)); // 將得到的對象加入results數組

  }

  // 如果只返回一個對象,直接返回該對象,如果返回了多個對象,則返回包含所有這些對象的數組

  return results.length < 2 ? results[0] : results;

}

從例2-1中可以看到,當$()只有1個輸入參數 時,它和document.getElementById是等效的,而當$()擁有多個輸入參數時,其返回值是一個Array對象,這個數組包含了所有符 合條件的對象。例2-2中分別用1個和多個參數調用了$()方法,注意示例中的黑體字。

例2-2  $()函數應用示例

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

    <head>

        <title>chapter 3</title>

        <script type="text/javascript" language="javascript"

         src="prototype.js" ></script>

        <script type="text/javascript" language="javascript">

        function test1() {

            var div = $("div1"); // 單個參數

            alert(div.innerHTML); // 輸出div1的HTML文本

        }

       

        function test2() {

            var divs = $("div1", "div2"); // 多個參數

            for (var i = 0; i < divs.length; i++) {

                alert(divs[i].innerHTML); // 依次輸出div1、div2的HTML文本

            }

        }

        </script>

    </head>

    <body>

    <div id="div1">

        div1

    </div>

    <div id="div2">

        div2

    </div>

    <input type="button" value="click1" οnclick="test1()" />

    <input type="button" value="click2" οnclick="test2()" />

    </body>

</html>

2.2.2  $A()函數

$A()函數可以將一個可枚舉的對象轉換爲一個Array對象,它和Array.from()是等效的。例2-3是Prototype中$A()函數的實現代碼。

例2-3  $A()函數

var $A = Array.from = function(iterable) {

  if (!iterable) return [];// 如果iterable對象不存在,返回空數組

  if (iterable.toArray) { // 如果iterable有toArray方法,返回iterable.toArray()

    return iterable.toArray();

  } else {

    var results = [];

    for (var i = 0; i < iterable.length; i++)

      results.push(iterable[i]);

    return results;//返回對象數組

  }

}

可以看到,$A()函數是通過兩種方式返回 Array對象的。第一種方式是如果傳入的對象已經實現了toArray方法,那麼則直接調用其toArray方法;第二種方式是通過循環的方式返回對象 的數組。使用第二種方式的前提是傳入的對象具有length屬性,並且可以通過序號索引其內部的所有對象。例2-4是$A()函數的應用示例,注意示例中 的黑體字。

例2-4  $A()函數應用示例

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

<head>

    <title>chapter 3</title>

    <script language="javascript" src="prototype.js"

     type="text/javascript"></script>

    <script language="javascript" type="text/javascript">

    function showOptions() {

        // 獲取所有option對象的集合

        var someNodeList = $("lstFramework").getElementsByTagName("option");

        // 通過$A方法把option對象的集合轉換爲Array對象

        var nodes = $A(someNodeList);

       

        var info = [];

       

        nodes.each (function(node){ // 遍歷nodes,添加到info數組中

            info.push(node.value + ": " + node.innerHTML);

        });

       

        alert(info.join("/r/n"));

    }

    </script>

</head>

<body>

    <form>

        <select id="lstFramework" size="10">

            <option value="1">Prototype</option>

            <option value="2">Script.aculo.us</option>

            <option value="3">Dojo</option>

            <option value="4">YUI</option>

        </select>

        <input οnclick="showOptions();" type="button" value="Show the options">

    </form>

</body>

</html>

圖2-1  $A函數應用示例

例2-4是通過點擊“Show the options”按鈕觸發onclick事件的響應函數showOptions,函數showOptions使用$A方法將lstFramework 的option對象集合轉換爲數組輸出,相應的輸出結果如圖2-1所示。

2.2.3  $F()函數

$F()是另一個經常使用的快捷方式,它是 Form.Element.getValue()函數的縮寫。$F()函數用來求得頁面中輸入控件的輸入值,它的輸入參數可以是目標控件的id值,也可以 是目標控件對象本身。$F支持的輸入控件包括<input>系列(即type=submit / hidden / password / text / checkbox / radio)、下拉列表<select>控件(多選的情況下,$F將會返回所有選中值的Array對象)和<textarea> 控件。例2-5給出了$F()函數的應用示例,該示例通過點擊按鈕觸發onclick事件的響應函數test,調用$F()方法獲得輸入控件 “username”的輸入值,然後輸出。

例2-5  $F()函數應用示例

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

    <head>

        <title>chapter 3</title>

        <script type="text/javascript" language="javascript"

         src="prototype.js" ></script>

        <script type="text/javascript" language="javascript">

        function test() {

            alert($F("userName"));

        }

        </script>

    </head>

    <body>

        <form>

            <input type="text" id="userName" value="test username">

            <input type="button" value="click" οnclick="test()">

        </form>

    </body>

</html>

2.2.4  $H()函數

Hash對象Prototype中定義了Hash對 象一個用於模擬Hash數據結構,$H()函數的功能是將對象轉換爲Hash對象。$H函數將Hash對象的方法和屬性通過Object.extend方 法擴展到目標對象上,這樣返回的對象就具有了Hash對象的方法,如keys方法,values方法等等。下面是$H()函數的一個應用示例:

<script>

function test() {

    // 創建一個對象

    var obj = {

        key1: 1,

        key2: 2,

        key3: 3

        };

    // 將其轉換爲Hash對象

    var hash = $H(obj);

    alert(hash.toQueryString());

}

</script>

2.2.5  $R()函數

$R()函數是new ObjectRange(start, end, exclusive)的縮寫形式,它根據指定的起始邊界返回相應的對象範圍。在Prototype中$R()函數的定義如例2-6所示。

例2-6  $R()函數定義

ObjectRange = Class.create();

Object.extend(ObjectRange.prototype, Enumerable);

Object.extend(ObjectRange.prototype, {

  initialize: function(start, end, exclusive) {

    this.start = start;

    this.end = end;

    this.exclusive = exclusive;

  },

  _each: function(iterator) {

    var value = this.start;

    do {

      iterator(value);

      value = value.succ();

    } while (this.include(value));

  },

  // include函數的作用是判斷value是否包含在對象範圍之內

  include: function(value) {

    if (value < this.start)

      return false;

    if (this.exclusive) // 注意exclusive參數僅在判斷上界是有效

      return value < this.end;

    return value <= this.end;

  }

});

var $R = function(start, end, exclusive) {

 // 定義$R方法,$R是new ObjectRange(start, end, exclusive)的一個簡單寫法或快捷方式

  return new ObjectRange(start, end, exclusive);

}

可以看到,ObjectRange類是由 Enumerable類繼承而來,它的初始化參數start、end和exclusive分別代表ObjectRange對象的下界、上界以及是否排除上 界的值。這裏需要注意的是,exclusive參數僅僅對上界起作用,從ObjectRange的include方法的實現代碼中不難看出這一點。例2- 7給出了$R()函數的應用示例,其中比較了exclusive參數分別爲true和false時的區別。

例2-7  $R()函數應用示例

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

    <head>

        <title>chapter 3</title>

        <script type="text/javascript" language="javascript"

         src="prototype.js" ></script>

        <script>

        // 依次輸出1,2,3,4

        function test_R1(){

            var range = $R(1, 5, true);

            range.each(function(value, index){

                alert(value);

            });

        }

        // 依次輸出1,2,3,4,5

        function test_R2(){

            var range = $R(1, 5, false);

            range.each(function(value, index){

                alert(value);

            });

        }

        </script>

    </head>

    <body>

        <form>

            <input type="button" value="click (exclusive = true)"

            οnclick="test_R1()" />

            <input type="button" value="click (exclusive = false)"

            οnclick="test_R2()" />

        </form>

    </body>

</html>

2.2.6  $$()函數

$$()函數是Prototype 1.5新增的一個快捷方式,它允許開發人員通過CSS樣式選擇頁面中的元素。熟悉XPath的讀者會發現,CSS選擇符在語法形式上和XML文檔的XPath十分類似,Prototype支持的CSS選擇符包括以下幾種類型:

l  元素標籤名稱,例如:$$(“li”)。

l  元素ID,例如:$$(“#fixtures”)。

l  CSS類名,例如:$$(“.first”)。

l  元素是否具有某個屬性,例如:$$(“h1[class]”)。

l  元素的某個屬性是否符合特定的條件,例如:$$('a[href="#"]')、$$('a[class~="internal"]')、$$('a[href!=#]')。

l  上面所有這些CSS選擇符的類型可以自由組合,形成一個複合的CSS選擇符,例如:$$('li#item_3[class][href!="#"]')。

l  不同的CSS選擇符(包括複合CSS選擇符)之間用空格分隔,就組成了一個多層的CSS選擇符,它通過指定目標元素的父節點甚至更多層父節點的CSS樣式屬性來定位目標元素。例如:$$('div[style] p[id] strong')。

例2-8給出了一個$$()函數的測試頁面示例,讀者可以在該頁面中輸入不同的CSS選擇符表達式,測試結果。

例2-8  $$()函數測試頁面

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

    <head>

        <title>chapter 3</title>

        <style type="text/css" media="screen">

        /* <![CDATA[ */

        #testcss1 { font-size:11px; color: #f00; }

        #testcss2 { font-size:12px; color: #0f0; display: none; }

        /* ]]> */

        </style>

        <script type="text/javascript" language="javascript"

         src="prototype.js" ></script>

        <script>

        function test() {

            // 根據輸入的CSS選擇符,切換相應元素的顯示

            $$($F('csspath')).each(

                function(item) {

                    Element.toggle(item);

                }

            );

        }

        </script>

    </head>

    <body>

        <form>

            <div id="fixtures">

              <h1 class="title">Some title <span>here</span></h1>

              <p id="p" class="first summary">

                <strong id="strong">This</strong> is a short blurb

                <!-- 該頁面元素具備 first和internal兩種CSS樣式-->

                <a id="link_1" class="first internal" href="#">with a link</a> or

                <a id="link_2" class="internal highlight" href="#">

                    <em id="em">two</em>

                </a>.

              </p>

              <ul id="list">

                <li id="item_1" class="first">

                    <a id="link_3" href="#" class="external">

                    <span id="span">Another link</span>

                    </a>

                </li>

                <li id="item_2">Some text</li>

                <li id="item_3" xml:lang="es-us" class="">Otra cosa</li>

              </ul>

            </div>

            <input type="text" value="" id="csspath" />

            <input type="button" value="click" οnclick="test()" />

        </form>

    </body>

</html>

例2-8的運行頁面如圖2-2所示,在文本輸入框中輸入一個CSS選擇符(例如“.title”),點擊“click”按鈕即可切換相應的頁面元素(即Some title here)的顯示/隱藏狀態。

   

 (a)  在文本輸入框中輸入CSS選擇符“.title”            (b)  頁面元素“Some title here”隱藏

圖2-2  $$函數應用示例

2.2.7  Try.these()函數

在程序開發的過程中有時會遇到這樣的情況:在若干個函數中開發人員不能確定哪一個會返回正確的結果,只能依次嘗試。Prototype中Try.these()函數爲開發人員提供了一個很簡便的方式來解決類似的問題。Try.these()函數的的定義如例2-9所示。

例2-9  Try.these()函數

var Try = {

  these: function() {

// 返回結果

    var returnValue;

    for (var i = 0; i < arguments.length; i++) {

// 輸入參數爲多個function對象

      var lambda = arguments[i];

      try {

// 如果其中一個函數成功返回,則返回該函數的結果

        returnValue = lambda();

        break;

      } catch (e) {}

    }

    return returnValue;

  }

}

從上述代碼中可以看到,Try.these()函數 的每一個參數都必須是一個無參的JavaScript方法。在Prototype框架中,實現Ajax對象的getTransport方法就用到了 Try.these()函數,getTransport方法的作用是返回一個XMLHttpRequest對象,而在不同瀏覽器中創建 XMLHttpRequest對象的方式是不同的。通過Try.these ()函數可以依次嘗試各種瀏覽器創建XMLHttpRequest對象的方法,直到成功爲止。例2-10所示爲Ajax對象的getTransport方 法的實現代碼。

例2-10  Ajax對象的getTransport方法的實現代碼

var Ajax = {

  getTransport: function() {

    // 嘗試以下3種創建XMLHttpRequest對象的方法

    // 1. Mozilla瀏覽器中的XMLHttpRequest對象

    // 2. 創建ActiveX對象"Msxml2.XMLHTTP"

    // 3. 創建ActiveX對象"Microsoft.XMLHTTP"

    return Try.these(

      function() {return new XMLHttpRequest()},

      function() {return new ActiveXObject('Msxml2.XMLHTTP')},

      function() {return new ActiveXObject('Microsoft.XMLHTTP')}

    ) || false;

  },

 

  // 當前活動的Ajax請求計數

  activeRequestCount: 0

}

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章