1. 程式人生 > >robin xiong的專欄

robin xiong的專欄

在這個教程裡,我們將解釋Dojo的事件標準化和dojo/keys以及如何使用dojo/keys來處理鍵盤事件。

開始

當鍵盤上的鍵被按下時會觸發鍵盤事件。 它包括所有的鍵, 字母,數字,符號, 標點符號, 以及刪除,功能,回車, tab和小鍵盤。 每鍵盤按鍵會觸發一個事件, 然後捕獲和處理。 瀏覽器本身都支援和實現對鍵盤事件的處理,但方法都不相同。 使用Dojo來處理鍵盤事件允許你寫的程式可以執行在所有的瀏覽器。

鍵盤事件

在瀏覽器裡監聽鍵盤事件允許你實現一個使用者介面,它不像看起來像本地的應用程式, 還為你提供了更大控制權的UI. onkeypress 當任何鍵被按下時直到鍵被釋放。 onkeypress可以用於大部分鍵盤事件的處理。 onkeydown
當任何鍵被按下時觸發,大部分情況下, onkeypress會在onkeydown之後觸發 。 onkeyup 當鍵被釋放(彈起)時觸發。 按大部分的鍵都會觸發上面的事件, 但在瀏覽器之者會有不同。 接下來的demo 允許你看到鍵盤按下後觸發的事件。 請花一些時間來試驗不同的鍵和組合。 Dojo  標準化了鍵盤事件, 使你可以通過dojo/keys 常量測試非列印鍵的輸入(可以輸出命令鍵的鍵值)。 比如我們建立一個表單, 通過向上和向下或者回來鍵來遍歷元素。  我們可以從一個簡單的例子開始:
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojo/dojo.js"
                data-dojo-config="async: true"> </script>
<body>
    <h1>Press any key</h1>
    keyCode value: <input type="text" id="keyCode" size="2">
</body>
require(["dojo/on", "dojo/domReady!"], function(on) {
    on(document, "keyup", function(event) {
        document.getElementById("keyCode").value = event.keyCode;
    });
});

檢視 Demo 這個例子簡單的展示瞭如何捕獲表單元素的鍵盤事件並且使用Dojo的標準化事件來某些事件(記錄到控制檯). 以下是: 但是你會發現,我們的例子沒有想向的那樣, 缺失了很多的功能, 如理回車, 這會在接下的例子裡講到。 !* 注間,dojo/on不像 dojo/_base/connect 的API,  事件名稱的字首如"onKeyup", 會省略掉 "on"。 可以檢視
Event with Dojo
獲得更多的資訊。

KeyboardEvent物件

如下圖所示, 當一個鍵盤事件觸發時,一個KeyboardEvent 會被傳遞給事件處理器。  這個事件對像包括很多關於這個事件的資訊。 但通常最需要的是keyCode的值。 它是按下鍵的unicode的值。
繼續之前的例子,我們可以使用dojo使它更加簡潔功能更加強大:
<body>
    <h1>Press Up or Down Arrow Keys</h1>
    <input type="text" id="input1" value="up">
    <input type="text" id="input2" value="down">
    <input type="submit" id="send" value="send">
</body>
require(["dojo/dom-construct", "dojo/on", "dojo/query", "dojo/keys", "dojo/domReady!"],
function(domConstruct, on, query, keys) {
    query("input[type='text']").on("keydown", function(event) {
        //query returns a nodelist, which has an on() function available that will listen
        //to all keydown events for each node in the list
        switch(event.keyCode) {
            case keys.UP_ARROW:
                event.preventDefault();
                //preventing the default behavior in case your browser
                // uses autosuggest when you hit the down or up arrow.
                log("up arrow has been pressed");
                break;
            case keys.DOWN_ARROW:
                event.preventDefault();
                //preventing the default behavior in case your browser
                // uses autosuggest when you hit the down or up arrow.
                log("down arrow has been pressed");
                break;
            case keys.ENTER:
                log("enter has been pressed");
                break;
            default:
                log("some other key: " + event.keyCode);
        }
    });
});

檢視 Demo 只需幾個改變, 我們消除了許多冗餘的程式碼, 並且使我們的角本更加強大 - 允許我們在單個事件處理函式裡,處理多種型別的按鍵(向上,向下,回車,普通字元)。 以及處理多個元素。 通過使用dojo/query,  獲得一個NodeList物件,通過NodeList的on方法給每個元素註冊監聽器。 它跟dojo/on模組的on()函式是完全一樣的,除了第一個引數省略之外。 這面這個例子使用了Dojo部分強大的功能, 但為了充分完成我們通過鍵盤事件來遍歷表單元素, 我們需要還需要更多的程式碼到我們的例子中, 以下是功能完全的一個例子:
<body>
    <h1>Press Up/Down Arrow Or Enter Keys to traverse form.</h1>
    <h2>Home/End will go to the beginning or end.</h2>
    <form id="traverseForm">
        First Name: <input type="text" id="firstName">
        Last Name: <input type="text" id="lastName">
        Email Address: <input type="text" id="email">
        Phone Number: <input type="text" id="phone">
        <input type="submit" id="send" value="send">
    </form>
</body>

require(["dojo/dom", "dojo/dom-construct", "dojo/on", "dojo/query", "dojo/keys", "dojo/NodeList-traverse", "dojo/domReady!"],
function(dom, domConstruct, on, query, keys) {
    var inputs = query("input");
 
    on(dom.byId("traverseForm"), "keydown", function(event) {
        var node = query.NodeList([event.target]);
        var nextNode;
 
        //on listens for the keydown events inside of the div node, on all form elements
        switch(event.keyCode) {
            case keys.UP_ARROW:
                nextNode = node.prev("input");
                if(nextNode[0]){
                    //if not first element
                    nextNode[0].focus();
                    //moving the focus from the current element to the previous
                }
                break;
            case keys.DOWN_ARROW:
                nextNode = node.next("input");
                if(nextNode[0]){
                    //if not last element
                    nextNode[0].focus();
                    //moving the focus from the current element to the next
                }
                break;
            case keys.HOME:
                inputs[0].focus();
                break;
            case keys.END:
                inputs[inputs.length - 2].focus();
                break;
            case keys.ENTER:
                event.preventDefault();
                //prevent default keeps the form from submitting when the enter button is pressed
                //on the submit button
                if(event.target.type !== "submit"){
                    nextNode = node.next("input");
                    if(nextNode[0]){
                        //if not last element
                        nextNode[0].focus();
                        //moving the focus from the current element to the next
                    }
                }else {
                    // submit the form
                    log("form submitted!");
                }
                break;
            default:
                log("some other key: " + event.keyCode);
        }
    });
});

檢視 Demo 我們在表單遍歷中使用了dojo/on的事件委託, 我們在form上註冊了單個的事件監聽器。 這個監聽器也可以監聽 form子元素的所有鍵盤事件。 事件委託顯然很有用, 我們只需對做很小的修改就可以處理文字框的輸入以及提交按紐。 這種解決方案還可以向上擴充套件; 如果有更多的表單元素被新增到我們的頁面, 我們的程式碼依然可以工作。 - 並且在dojo/on模組對事件標準化和dojo/keys 常量模組的幫助下。 它可以在跨瀏覽器和平臺工作。

digit/_keyNavMixin中的鍵盤導航

最後,如果你的首要目標是處理導航上的鍵盤事件, 你可以使用digit/_KeyNavMixin.  它需要在你的視窗部件中定義一些導航事件處理函式, 一旦你滿足了它的要求, 它會監聽和響應導航相關的鍵盤事件。 我們不會在這個教程裡詳細講,但你可以檢視相關教程,以下是一個簡單的 demo.

總結

Dojo使用dojo/on來使事件標準化。 用它可以非常簡單的處理不同瀏覽器下的鍵盤事件。 使用 dojo/on和 dojo/keys, 我們建立了一個表單, 擴充套件了up/down和回車鍵。 

更多資源

關於dojo/on的更多細節和和其它的在這個教程中使用到的工具: