国产精品毛片一区二区,欧美熟妇brazzers,丰满女邻居的嫩苞张开视频,天天爽夜夜爽夜夜爽

南京北大青鳥

全國咨詢電話:15195455103

三分鐘了解北大青鳥
當(dāng)前位置:南京北大青鳥 > 課程設(shè)置 > ACCP課程JAVA技術(shù)

用 JavaScript 創(chuàng)建模塊化的交互用戶界面

來源:張玉清? ? ? 作者:IT教育 ? ??

通過本文,了解使用拖放功能移動 Web 頁面的不同部分的技巧。分別實(shí)現(xiàn)交互性的不同方面,然后再將它們組合在一起,這樣便于靈活定制頁面,也讓您的 Web 用戶非常滿意。 JavaScript 是
通過本文,了解使用拖放功能移動 Web 頁面的不同部分的技巧。分別實(shí)現(xiàn)交互性的不同方面,然后再將它們組合在一起,這樣便于靈活定制頁面,也讓您的 Web 用戶非常滿意。
JavaScript 是一種功能強(qiáng)大的語言,可用于創(chuàng)建基于 Web 的應(yīng)用程序。它已經(jīng)足夠穩(wěn)定和成熟,完全可以創(chuàng)建與傳統(tǒng)桌面應(yīng)用程序相抗衡的程序,因?yàn)楹笳咴诜€(wěn)定性和特性豐富性方面都要勝出一籌。但 JavaScript 初只是用來向靜態(tài) Web 頁面添加某些交互性,使它不再是靜態(tài)頁面,它現(xiàn)在還用于此目的。
我將要展示的這個技巧 的關(guān)鍵之處是如何恰當(dāng)?shù)貥?gòu)建頁面,使它能與 JavaScript 代碼交互。通常,頁面都是通過頭腦里固有的 JavaScript 代碼構(gòu)造的。但是,盡管如此,很多時候您都需要向現(xiàn)有頁面內(nèi)添加新的交互特性。而這往往需要一些技巧,因?yàn)?JavaScript 代碼必須遍歷文檔結(jié)構(gòu)并在合適的位置添加代碼,而且通常還要求不影響現(xiàn)有的結(jié)構(gòu) — 和頁面上已有的 JavaScript 代碼??傊獙ο到y(tǒng)的影響小化。
常見的縮寫詞
  • UI用戶界面
  • GUI圖形用戶界面
  • HTML超文本標(biāo)記語言
  • XML可擴(kuò)展標(biāo)記語言
  • DOM文檔對象模型
可切換系統(tǒng)
本文介紹了一種方法,它通過移動頁面的不同部分來激活 頁面。具體來講,就是通過將一個部分拖放到另一個部分之上從而實(shí)現(xiàn)可切換 部分的切換。
要激活這些部分,只需向其添加 class 參數(shù)并加載一個 JavaScript 文件??梢酝ㄟ^向 <body> 標(biāo)記添加 onload 方法來激活代碼,此方法會在頁面加載之后立即啟動代碼。代碼會處理隨后的事情。
注意:本文示例所對應(yīng)的源代碼可以從 下載 部分獲得。
此外,可以盡量多地使用抽象來構(gòu)造代碼。程序的不同元素通常都不必要地相互纏結(jié),UI 代碼更是這樣??汕袚Q系統(tǒng)由不同的塊構(gòu)建而成,每個塊實(shí)現(xiàn)交互性的不同部分。這些塊結(jié)合起來就能實(shí)現(xiàn)簡單無縫的界面,該界面對于 UI 的試驗(yàn)和調(diào)優(yōu)都很關(guān)鍵。
回頁首
可切換界面
可切換系統(tǒng)很容易使用。先由 Web 頁面設(shè)計(jì)人員將某些部分標(biāo)志為可切換的。然后就可以在任何一個可切換元素上單擊并將該元素拖放到另一個可切換元素。放開鼠標(biāo)按鈕后,這兩個元素就完成了交換。
為了能清楚展示所發(fā)生的事情,可以使用一些標(biāo)準(zhǔn)的 GUI 操作。
突出顯示被拖動的元素
當(dāng)?shù)谝淮螁螕艨汕袚Q元素時,在光標(biāo)下面會出現(xiàn)一個透明的矩形。這個矩形由 coveringDiv() 函數(shù)創(chuàng)建,它剛好能覆蓋這個可切換元素。實(shí)際上是將這個矩形拖放到另一個元素。當(dāng)拖放時,只有這個透明的矩形會移動 — 初始的元素保持不動直到鼠標(biāo)按鈕被松開為止。
突出顯示拖動到的目標(biāo)
另一個重要的操作是清晰標(biāo)識出要拖動到的目標(biāo)元素。當(dāng)拖動 透明的矩形四處移動時,光標(biāo)可以經(jīng)過多個可切換元素。當(dāng)光標(biāo)懸浮于某個可切換元素之上時,該元素就會通過另一個透明矩形突出顯示。這種突出顯示就能清楚地 標(biāo)示出此元素就是拖放到的目標(biāo)。當(dāng)松開鼠標(biāo)按鈕時,被拖動的元素和拖放到的目標(biāo)元素就會互換位置,而且所有透明矩形也會消失,直到下一次切換。
激活系統(tǒng)
正如先前提到的,必須要使代碼對已有系統(tǒng)影響小。這就意味著頁面設(shè)計(jì)人員 —工作于 HTML 或 XML— 無需涉及可切換系統(tǒng)。這不是他們的工作。
此頁面只需具有如下三項(xiàng)內(nèi)容:
  • JavaScript 標(biāo)記
  • <body> 標(biāo)記內(nèi)的 onload 方法
  • 標(biāo)記為 swappable 的可切換區(qū)域
JavaScript 標(biāo)記
必須將以下標(biāo)記置于頁面文件的頂部:
<script src="rearrange-your-page.js"></script>
此標(biāo)記在加載過程的早期加載,但它在 body 內(nèi)的 onload 函數(shù)調(diào)用之后才會執(zhí)行。
body 標(biāo)記內(nèi)的 Onload 方法
該方法在整個頁面加載時調(diào)用這個可切換系統(tǒng)。這一點(diǎn)很重要,因?yàn)榇舜a的第一項(xiàng)功能就是在整個頁面內(nèi)搜索可切換的元素。因而,需要確保這些元素已加載。body 內(nèi)的 onload 方法應(yīng)該如清單 1 所示。
清單 1. body 內(nèi)的 onload 處理程序
<body onload="swappable_start();">
    ... rest of page
  </body>
已標(biāo)記為 swappable 的可切換區(qū)域
必須通過 class 參數(shù)這樣標(biāo)記每個想要切換的區(qū)域。這是頁面作者和設(shè)計(jì)人員需要多加考慮的事情,因?yàn)樗麄冃枰獙⒋藚?shù)添加給每個部分。參見清單 2。
清單 2. 用可切換類注釋 div
<div class='swappable'>
    lorem ipsum lorem ipsum
  </div>
尋找可切換的部分
代碼所需做的首要事情是尋找頁面將被激活的部分。正如之前提到的,這只要求包圍這個部分的標(biāo)記具有 class 參數(shù)。要尋找這些部分,需要找到所有具有可切換 class 的標(biāo)記。此函數(shù)不是標(biāo)準(zhǔn) DOM 庫的一部分,但它很容易實(shí)現(xiàn)。清單 3 展示了一個示例實(shí)現(xiàn)。
清單 3. getElementsByClass() 的實(shí)現(xiàn)
// By Dustin Diaz
function getElementsByClass(searchClass,node,tag) {
        var classElements = new Array();
        if ( node == null )
                node = document;
        if ( tag == null )
                tag = '*';
        var els = node.getElementsByTagName(tag);
        var elsLen = els.length;
        var pattern = new RegExp("(^|\\\\s)"+searchClass+"(\\\\s|$)");
        for (i = 0, j = 0; i < elsLen; i++) {
                if ( pattern.test(els[i].className) ) {
                        classElements[j] = els[i];
                        j++;
                }
        }
        return classElements;
}
交互性的元素
程序一般是通過將各功能塊結(jié)合在一起而構(gòu)建起來的。不同的程序員會有不同的實(shí)現(xiàn)方式,但作為一種規(guī)律,好是采用多個小的功能塊而不是少數(shù)幾個大的功能塊。每個小功能塊應(yīng)該實(shí)現(xiàn)一種功能并具有清楚的語義。
不過,在進(jìn)行 GUI 編程時,這樣的構(gòu)建不太容易。好的 GUI 必須調(diào)整很多界面元素并將它們的行為結(jié)合起來形成一個能直觀工作的整體行為。基于事件的系統(tǒng)通常都是由復(fù)雜的交換行為聯(lián)合起來的回調(diào)集合。模塊化的交互元素很難創(chuàng)建。
模塊化的交互元素
可切換代碼就使用了模塊化的交互元素。前面,我提到過在可切換系統(tǒng)內(nèi)有兩種主要的交互元素:拖動元素的突出顯示和拖動到的目標(biāo)的突出顯示。在代碼中,這兩個元素的實(shí)現(xiàn)是分開的。
本例很好地展示了模塊化處理交互性的技巧。正如可切換界面的描述中所提到的,這兩個交互性元素常常纏結(jié)在一起。突出顯示和突出顯示的 消失都是在一個鼠標(biāo)操作中發(fā)生的,而且它們的發(fā)生都對應(yīng)鼠標(biāo)輸入的不同方面。如果這兩個元素是在一個代碼片段中實(shí)現(xiàn)的,那么代碼可能不太容易讀懂,因?yàn)橥?時發(fā)生的事情很多。
拖動處理程序
為了使 GUI 的實(shí)現(xiàn)模塊化,我使用了拖動處理程序。這類似于內(nèi)置在 GUI 系統(tǒng)的事件處理程序。雖然事件處理程序只處理某種單一事件,拖動處理程序卻可以處理整個拖放過程。一個拖動處理程序可處理一系列事件而不只一個單一事件。下面是拖動處理程序的示例骨架,如清單 4 所示。
清單 4. 拖動處理程序的骨架
{
    start:
      function( x, y ) {
        // ...
      },
 
    move:
      function( x, y ) {
        // ...
      },
 
    done:
      function() {
        // ...
      },
  }
這個拖動處理程序是一個對象,具有三個方法:start、move 和 done。當(dāng)初始化一個拖放動作時,調(diào)用 start 方法并傳遞給這次單擊的對應(yīng)坐標(biāo)。當(dāng)四處移動光標(biāo)時,會反復(fù)調(diào)用 move 方法,然后同樣被傳遞給光標(biāo)當(dāng)前對應(yīng)的坐標(biāo)。后,當(dāng)鼠標(biāo)按鈕釋放后,就會調(diào)用 done 方法。
可切換系統(tǒng)同時使用了兩個不同的拖動處理程序,這也讓您能夠干凈地處理交互的兩個不同方面,即便這兩個方面具有復(fù)雜的關(guān)系。讓其中的一個交互成為另一個交互的一部分并不合適。相反,應(yīng)該能同時無縫地使用這兩個交互。
rectangle_drag_handler
這兩個拖放處理程序的其中是 rectangle_drag_handler。此處理程序負(fù)責(zé)移動代表被拖動元素的透明矩形。清單 5 給出了這個 start 方法。
清單 5. rectangle_drag_handler 處理程序
function rectangle_drag_handler( target )
  {
    this.start = function( x, y ) {
      this.cover = coveringDiv( target );
      make_translucent( this.cover, .6 );
      this.cover.style.backgroundColor = "#777";
      dea( this.cover );
 
      this.dragger = new dragger( this.cover, x, y );
    };
    // ...
  }
start 方法創(chuàng)建這個透明矩形并將其傳遞給另一個稱為 dragger 的對象。一個 dragger 就是一個對象,它能對應(yīng)移動的光標(biāo)移動 DOM 元素??梢詫?dāng)前的光標(biāo)的坐標(biāo)傳遞給這個 dragger,它會更新所拖動的對象使其跟隨光標(biāo)的移動。
move 方法更新這個 dragger,如清單 6 所示。
清單 6. 更新 dragger
this.move = function( x, y ) {
    this.dragger.update( x, y );
  };
后,done 方法(參見清單 7)刪除這個透明矩形,因?yàn)橥戏胚^程現(xiàn)在已經(jīng)結(jié)束。
清單 7. rectangle_drag_handler 的 done 方法
this.move = function( x, y ) {
    this.done = function() {
      this.cover.parentNode.removeChild( this.cover );
    };
}
組合拖動處理程序
現(xiàn)在必須找到一種方法來同時使用這兩個拖動處理程序。這可以通過 compose_drag_handlers() 函數(shù)輕松實(shí)現(xiàn),該函數(shù)接受這兩個拖動處理程序并將其結(jié)合成一個綜合的拖動處理程序。這個綜合拖動處理程序的使用與一般的拖動處理程序一樣。這樣,這兩個原始的拖動處理程序的行為就實(shí)現(xiàn)了無縫結(jié)合。
compose_drag_handlers() 函數(shù)很容易編寫。它看上去很像是一個拖動處理程序,但每個方法都會調(diào)用這兩個原始拖動處理程序中相應(yīng)的方法。這個函數(shù)如清單 8 所示。
清單 8. compose_drag_handlers()
function compose_drag_handlers( a, b )
  {
    return {
    start:
      function( x, y ) {
        a.start( x, y );
        b.start( x, y );
      },
 
    move:
      function( x, y ) {
        a.move( x, y );
        b.move( x, y );
      },
 
    done:
      function() {
        a.done();
        b.done();
      },
    }
  }
正如您所見,拖動處理程序 a 和 b 被組合到一個綜合的拖動處理程序內(nèi)。如果要調(diào)用這個綜合處理程序的 start() 方法,實(shí)際上就是先后調(diào)用 a.start() 和 b.start()。
您需要在名為 prepare_swappable() 的設(shè)置函數(shù)內(nèi)調(diào)用 compose_drag_handlers,如清單 9 所示。
清單 9. prepare_swappable() 函數(shù)
function prepare_swappable( o )
  {
    swappables.push( o );
    var sdp = new rectangle_drag_handler( o );
    var hdp = new highlighting_drag_handler( o );
    var both = compose_drag_handlers( sdp, hdp );
    install_drag_handler( o, both );
  }
除了其他功能之外,此函數(shù)主要的功能是為可切換元素創(chuàng)建 rectangle_drag_handler 和 highlighting_drag_handler,然后再將它們組合成一個綜合的拖動處理程序。后,這個綜合拖動處理程序再通過調(diào)用 install_drag_handler() 來激活,這將在接下來的兩個小節(jié)中詳細(xì)介紹。
安全安裝鼠標(biāo)處理程序
與常規(guī)的事件處理程序不同,一個拖動處理程序可以處理多個事件。盡管如此,它還是需要附加到對象,這與常規(guī)的事件處理程序相同。
安裝任何一種事件處理程序都是需要技巧的,因?yàn)檎谛薷牡脑睾芸赡芤呀?jīng)在其內(nèi)安裝了事件處理程序。如果要替換這些事件處理程序,就需要更改頁面的行為方式。
為了避免這一問題,可以使用一個名為 install_mouse_handlers() 的實(shí)用函數(shù),如清單 10 所示。
清單 10. install_mouse_handlers() 函數(shù)
function install_mouse_handlers( target, onmouseup, onmousedown, onmousemove )
  {
    var original_handlers = {
      onmouseup: target.onmouseup,
      onmousedown: target.onmousedown,
      onmousemove: target.onmousemove
    };
 
    target.onmouseup = onmouseup;
    target.onmousedown = onmousedown;
    target.onmousemove = onmousemove;
 
    return {
      restore: function() {
        target.onmouseup = original_handlers.onmouseup;
        target.onmousedown = original_handlers.onmousedown;
        target.onmousemove = original_handlers.onmousemove;
       }
    };
  }
install_mouse_handlers() 函數(shù)負(fù)責(zé)向特定的對象添加特定的鼠標(biāo)處理程序。它返回的是一個對象,可使用該對象恢復(fù)原始的處理程序。這樣一來,當(dāng)拖放過程結(jié)束后,就可以調(diào)用 restore() 函數(shù),恢復(fù)到拖放過程開始之前的狀態(tài)。
激活拖動處理程序
針對拖放操作的拖動處理程序使用了這三個鼠標(biāo)處理程序:onmousedown、onmouseup 和 onmousemove。不過,開始時,只需安裝 mousedown 處理程序,因?yàn)榇藭r您尚在等待激發(fā)初始化拖放過程的單擊。
當(dāng)單擊發(fā)生時,就需要安裝 mousemove 和 mouseup 處理程序。而且,在此時,不再需要 mousedown 處理程序,因?yàn)橐呀?jīng)進(jìn)行單擊。該處理程序?qū)⒈粍h除,在拖放過程完成后再恢復(fù)它。初的 mousedown 處理程序如清單 11 所示。
清單 11. 初的 mousedown 處理程序
var onmousedown = function( e ) {
    var x = e.clientX;
    var y = e.clientY;
 
    p.start( x, y );
 
    var target_handler_restorer = null;
    var document_handler_restorer = null;
 
    var onmousemove = function( e ) {
      var x = e.clientX;
      var y = e.clientY;
 
      p.move( x, y );
    };
 
    var onmouseup = function( e ) {
      p.done();
      target_handler_restorer.restore();
      document_handler_restorer.restore();
    };
 
    target_handler_restorer =
      install_mouse_handlers( target, onmouseup, null, onmousemove );
    document_handler_restorer =
      install_mouse_handlers( document, onmouseup, null, onmousemove );
 
    e.stopPropagation();
 
    return false;
  };
在初始化拖放序列并調(diào)用此處理程序時,它會創(chuàng)建 onmousemove 和 onmouseup 處理程序并能在目標(biāo)元素內(nèi)安裝它們。當(dāng)然,它還會使用一個 install_mouse_handlers(),以便以后的卸載。
還有一點(diǎn)需要注意:是在 document 對象內(nèi)安裝這些處理程序的。這一點(diǎn)十分關(guān)鍵,因?yàn)樵谕戏胚^程中用戶可能會將光標(biāo)拖過整個頁面。如果鼠標(biāo)超出可切換元素的范圍 — 您很可能還想收到這些事件。同樣地,可以使用 install_mouse_handlers() 以便以后恢復(fù)它們。
回頁首
將它們組合起來
至此,我已經(jīng)介紹了很多不同的類和函數(shù)。其中的每一個類或函數(shù)本身都十分簡單,因此更重要的是要了解它們是如何協(xié)同工作的。
下面是對整個拖放過程的一個總結(jié):
  • 單擊一個可切換元素。
  • 此元素的 onmousedown 處理程序?qū)⒈徽{(diào)用,它安裝 onmousemove 和 onmouseup 處理程序。
  • 移動鼠標(biāo),這些處理程序?qū)⒈徽{(diào)用。
  • 這些處理程序反過來調(diào)用前面安裝的拖動處理程序。
  • 這個拖動處理程序?qū)嶋H上是一個復(fù)合拖動處理程序,綜合了兩個不同的拖動處理程序的效果。
  • 其中的一個拖動處理程序 rectangle_drag_handler 負(fù)責(zé)向光標(biāo)附加一個代表被拖動元素的透明矩形。
  • 另一個拖動處理程序 highlighting_drag_handler 負(fù)責(zé)突出顯示鼠標(biāo)移過的那些可切換元素,以顯示可以進(jìn)行元素拖動的地方。
  • 當(dāng)在目標(biāo)元素之上釋放鼠標(biāo)按鈕時,highlighting_drag_handler 的 done() 方法就會切換這兩個元素。這個拖動處理程序?qū)⒈恍遁d,只留下初的 onmousedown 處理程序,準(zhǔn)備好開始下一輪的拖放過程。
結(jié)束語
拖放操作相對簡單,但它涉及了幾個交互過程,用來跟蹤整個過程的用戶輸入和提供即時反饋。本文展示如何將模塊化的交互元素組合成統(tǒng)一整體來構(gòu)建完整的 GUI。
這種做法有很多好處。由于代碼是模塊化的,因此更容易編寫和維護(hù)。所需的函數(shù)和類的代碼沒有一個是超過 40 行的,并且它們通常更短。
每一個交互元素都會實(shí)現(xiàn)一個典型的 GUI 過程或效果,所以可在其他上下文中重用它們??梢蚤_發(fā)這些交互元素的豐富的庫,從而通過組合各個部分構(gòu)建更復(fù)雜的 UI。
 

分享到:
近期文章

搶試聽名額

名額僅剩66名

教育改變生活

WE CHANGE LIVES