概述
自訂事件很難派上用場?
為什麼自訂事件很難派上用場,因為以前js不是模組化開發,也很少協作。因為事件本質是一種通訊方式,是一種訊息,只有存在多個對象,多個模組的情況下,才有可能需要用到事件進行通訊。而現在有了模組化之後,已經可以使用自訂事件進行各模組間協作了。
哪裡用得到自訂事件?
事件本質是一種訊息,事件模式本質上是觀察者模式的實現,那麼用得上觀察者模式的地方,自然也可以也可以用上事件模式。所以,如果:
1、一個目標物改變,需要多個觀察者調整自己的。
例如:我需要元素A點擊之後,元素B顯示滑鼠的位置,元素C顯示提示,元素D.....
2、分模組協作需要解耦的
例如:甲負責模組A,乙負責模組B,模組B需要A運行完之後才能運行
#傳統的寫法將邏輯寫在一個方法裡面:
function doSomething(){ A(); B(); }
這樣做每次擴充都要修改a的點擊函數,不好擴充。
自訂事件的寫法
//1、创建事件 var clickElem = new Event("clickElem"); //2、注册事件监听器 elem.addEventListener("clickElem",function(e){ //干点事 }) //3、触发事件 elem.dispatchEvent(clickElem);
可以看到,elem透過dispatchEvent方法觸發的事件,只有elem上註冊的監聽器才能監聽得到。這就很沒意思了,自己發給自己訊息,通知自己要去做什麼。
建立自訂事件可參考: MDN : Creating_and_triggering_events
應用程式
##從前面js 自訂事件的描述中知道:元素A透過dispatchEvent方法觸發的事件,只有A上註冊的監聽器才能監聽得到。 我們想要的效果是,別的對象乾了某件事之後, 發個訊息給我們,好讓我們能做相應的改變。要做到這樣,也不是沒辦法:我們可以在一個公共物件上監聽和觸發事件,這就很有意義了。範例一:通知多個物件
要實現元素A點擊之後,元素B顯示滑鼠的位置,元素C顯示提示,可以這樣寫:檔:a.jsimport b from "./b" import c from "./c" var a = document.getElementById("a"); a.addEventListener("click",function(e){ var clickA = new Event("clickA"); document.dispatchEvent(clickA); });注意:import進來的變數雖然不使用,但一定不能省略檔b.js:
var b = document.getElementById("b"); document.addEventListener("clickA",function(e){ b.innerHTML = "(128,345)"; })檔c .js:
var c = document.getElementById("c"); document.addEventListener("clickA",function(e){ c.innerHTML = "你点了A"; })這樣寫,三個模組之間完全不用關心對象,也不知道對方存在,耦合度非常的低,完全可以獨立寫,不會互相影響。這其實就是一個觀察者模式的實現。
範例二:遊戲框架
要開發一個遊戲,啟動遊戲,載入圖片和音樂,載入完後,渲染場景和音效,載入和渲染由不同的人負責。可以這樣寫:檔:index.jsimport loadImage from "./loadImage" import loadMusic from "./loadMusic" import initScene from "./initScene" var start = document.getElementById("start"); start.addEventListener("click",function(e){ console.log("游戏开始!"); document.dispatchEvent(new Event("gameStart")); })檔:loadImage.js
// 加载图片 document.addEventListener("gameStart",function(){ console.log("加载图片..."); setTimeout(function(){ console.log("加载图片完成"); document.dispatchEvent(new Event("loadImageSuccess")); },1000); });檔:loadMusic.js
//加载音乐 document.addEventListener("gameStart",function(){ console.log("加载音乐..."); setTimeout(function(){ console.log("加载音乐完成"); document.dispatchEvent(new Event("loadMusicSuccess")); },2000); });檔:initScene. js
//渲染场景 document.addEventListener("loadImageSuccess",function(e){ console.log("使用图片创建场景..."); setTimeout(function(){ console.log("创建场景完成"); },2000) }); //渲染音效 document.addEventListener("loadMusicSuccess",function(e){ console.log("使用音乐创建音效..."); setTimeout(function(){ console.log("创建音效完成"); },500) });載入模組和渲染模組互不影響,易於擴充。
攜帶訊息
除此之外,事件還能傳遞自訂訊息:var event = new CustomEvent('myEvent', { 'dataName': dataContent }); document.dispatchEvent(event);(注意:傳遞自訂訊息需要使用CustomEvent ,而不是Event)然後在監聽函數裡取出:
document.addEventListener("myEvent",function(e){ console.log(e.dataName); })
以上是怎麼用javascript實作自訂事件功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!