如何在JavaScript中使用自定義事件

jopen 12年前發布 | 54K 次閱讀 JavaScript開發 JavaScript

JavaScript 的事件處理是所有瀏覽器端程序的基本必備技巧。當目標元素的事件被觸發時,比如按鈕被點擊,鼠標移動,或者是表單提交,這些事件觸發時都可以觸發對應的方法。當然這個過程中我們可以傳遞一些參數過去來自定義很多事情。


一個要注意避免的就是事件與DOM元素的緊耦合。比如先看看下面這個代碼,考慮到用一個簡單表單來接受用戶輸入的信息。
<form id="msgbox" action="#" method="get">
<label for="msg">your message</label>
<input id="msg" value="" />
<button>SEND</button>
</form>


我們能寫一段代碼讓屏幕上顯示剛才表單提交的信息
document.getElementById("msgbox").addEventListener("submit", function(e) {
    e.preventDefault();
    var msg = e.currentTarget.getElementById("msg").value.trim();
    if (msg) {
        alert(msg);
    }
}, false);


那么如果我們想對顯示出來的這句話做一些操作,比如發一條tweet,或存儲在服務器或者干些其他什么?則有兩個選擇:
1,對已有的事件處理方法添加代碼
   這個方案的缺陷就是每當打算測試或者更新后來添加的事件處理方法時變得非常不彈性化,每當更改或者刪除一些功能的時候,總會有一大段代碼要跟著去修改。

2,為每一個功能都創建事件處理方法
   第二個方法很好的解決了前面方法的問題,雖然這個方法可能會一開始麻煩點。畢竟所有的方法代碼都要處理重復的消息提取以及驗證步驟。

設想假如能夠自行觸發自定義的"newMessage"事件而無需驗證是否有message提交,或假如能監控整個HTML文檔或者body這樣的標簽而不僅僅只是某個表單的節點,能否做到呢?這就是自定義事件要解決的問題了。

自行觸發一個自定義事件是很簡單的;如下代碼就是傳遞一個name,details以及options到新建的 CustomEvent對象中:
var event = new CustomEvent(
    "newMessage",
    {
        detail: {
            message: "Hello World!",
            time: new Date(),
        },
        bubbles: true,
        cancelable: true
    }
);



這個案例中,"newMessage"是一個自定義事件類型。而第二個參數包含了此對象的三個屬性(detail,bubbles,cancelable)。

detail: 包含了自定義事件的具體信息,這里僅僅就包括了一個message與一個time
bubbles: 如果是true,則事件會一直傳遞給自身的父對象元素,接著父對象也會觸發此類事件
cancelable: 如果是true, 事件可以被事件觸發元素的 stopPropagation( ) 方法停止

現在,我們需要針對某個特定元素來觸發此類事件。
document.getElementById("msgbox").dispatchEvent(event);


可以用以下代碼訂閱這個事件的處理。
document.addEventListener("newMessage", newMessageHandler, false);


展示頁
查看自定義事件的展示頁
一個標準的事件處理方法將會查看提交到HTML表單的所有信息。下面這個方法先獲取當前的消息,假設它已經被驗證,最后自行觸發一個新的"newMessage"的事件。
var msgbox = document.getElementById("msgbox");
msgbox.addEventListener("submit", SendMessage, false);
// new message: raise newMessage event
function SendMessage(e) {
    e.preventDefault();
    var msg = document.getElementById("msg").value.trim();
    if (msg && window.CustomEvent) {
        var event = new CustomEvent("newMessage", {
            detail: {
                message: msg,
                time: new Date(),
            },
            bubbles: true,
            cancelable: true
        });
        e.currentTarget.dispatchEvent(event);
    }
}


所有的事件處理方法都可以訂閱來處理那個 newMessage 事件。
// listen for newMessage event
document.addEventListener("newMessage", newMessageHandler, false);
// newMessage event handler
function newMessageHandler(e) {
    LogEvent(
        "Event subscriber on "+e.currentTarget.nodeName+", "
        +e.detail.time.toLocaleString()+": "+e.detail.message
    );
}


瀏覽器能力
不過上面這個 CustomEvent對象只有在 Chrome, FireFox以及Opera才能正常使用。而下一個版本的Safari也支持了。IE9以及更低版本暫時是不支持的。
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!