您好,登錄后才能下訂單哦!
今天小編給大家分享一下javascript怎么實(shí)現(xiàn)自定義事件功能的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。
概述
自定義事件很難派上用場(chǎng)?
為什么自定義事件很難派上用場(chǎng),因?yàn)橐郧癹s不是模塊化開(kāi)發(fā),也很少協(xié)作。因?yàn)槭录举|(zhì)是一種通信方式,是一種消息,只有存在多個(gè)對(duì)象,多個(gè)模塊的情況下,才有可能需要用到事件進(jìn)行通信。而現(xiàn)在有了模塊化之后,已經(jīng)可以使用自定義事件進(jìn)行各模塊間協(xié)作了。
哪里用得到自定義事件?
事件本質(zhì)是一種消息,事件模式本質(zhì)上是觀(guān)察者模式的實(shí)現(xiàn),那么用得上觀(guān)察者模式的地方,自然也可以也可以用上事件模式。所以,如果:
1、一個(gè)目標(biāo)對(duì)象改變,需要多個(gè)觀(guān)察者調(diào)整自身的。
比如:我需要元素A點(diǎn)擊之后,元素B顯示鼠標(biāo)的位置,元素C顯示提示,元素D.....
2、分模塊協(xié)作需要解耦的
比如:甲負(fù)責(zé)模塊A,乙負(fù)責(zé)模塊B,模塊B需要A運(yùn)行完之后才能運(yùn)行
傳統(tǒng)的寫(xiě)法將邏輯寫(xiě)在一個(gè)方法里面:
function doSomething(){ A(); B(); }
這樣做每次擴(kuò)展都要修改a的點(diǎn)擊函數(shù),不好擴(kuò)展。
自定義事件的寫(xiě)法
//1、創(chuàng)建事件 var clickElem = new Event("clickElem"); //2、注冊(cè)事件監(jiān)聽(tīng)器 elem.addEventListener("clickElem",function(e){ //干點(diǎn)事 }) //3、觸發(fā)事件 elem.dispatchEvent(clickElem);
可以看到,elem通過(guò)dispatchEvent方法觸發(fā)的事件,只有elem上注冊(cè)的監(jiān)聽(tīng)器才能監(jiān)聽(tīng)得到。這就很沒(méi)意思了,自己發(fā)給自己消息,通知自己去干什么。
創(chuàng)建自定義事件可參考: MDN : Creating_and_triggering_events
應(yīng)用
從前面 js 自定義事件 的描述中知道:元素A通過(guò)dispatchEvent方法觸發(fā)的事件,只有A上注冊(cè)的監(jiān)聽(tīng)器才能監(jiān)聽(tīng)得到。
我們想要的效果是,別的對(duì)象干了某件事之后, 發(fā)個(gè)消息給我們,好讓我們能做相應(yīng)的改變。要做到這樣,也不是沒(méi)辦法:我們可以在一個(gè)公共對(duì)象上監(jiān)聽(tīng)和觸發(fā)事件,這就很有意義了。
例子一:通知多個(gè)對(duì)象
要實(shí)現(xiàn) 元素A點(diǎn)擊之后,元素B顯示鼠標(biāo)的位置,元素C顯示提示,可以這樣寫(xiě):
文件:a.js
import 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進(jìn)來(lái)的變量雖然不使用,但是一定不能省略
文件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 = "你點(diǎn)了A"; })
這樣寫(xiě),三個(gè)模塊之間完全不用關(guān)心對(duì)象,也不知道對(duì)方存在,耦合度非常的低,完全可以獨(dú)立編寫(xiě),不會(huì)互相影響。這其實(shí)就是一個(gè)觀(guān)察者模式的實(shí)現(xiàn)。
例子二:游戲框架
要開(kāi)發(fā)一個(gè)游戲,啟動(dòng)游戲,加載圖片和音樂(lè),加載完后,渲染場(chǎng)景和音效,加載和渲染由不同的人負(fù)責(zé)。可以這樣寫(xiě):
文件:index.js
import loadImage from "./loadImage" import loadMusic from "./loadMusic" import initScene from "./initScene" var start = document.getElementById("start"); start.addEventListener("click",function(e){ console.log("游戲開(kāi)始!"); 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
//加載音樂(lè) document.addEventListener("gameStart",function(){ console.log("加載音樂(lè)..."); setTimeout(function(){ console.log("加載音樂(lè)完成"); document.dispatchEvent(new Event("loadMusicSuccess")); },2000); });
文件:initScene.js
//渲染場(chǎng)景 document.addEventListener("loadImageSuccess",function(e){ console.log("使用圖片創(chuàng)建場(chǎng)景..."); setTimeout(function(){ console.log("創(chuàng)建場(chǎng)景完成"); },2000) }); //渲染音效 document.addEventListener("loadMusicSuccess",function(e){ console.log("使用音樂(lè)創(chuàng)建音效..."); setTimeout(function(){ console.log("創(chuàng)建音效完成"); },500) });
加載模塊和渲染模塊互不影響,易于擴(kuò)展。
攜帶信息
除此之外,事件還能傳遞自定義信息:
var event = new CustomEvent('myEvent', { 'dataName': dataContent }); document.dispatchEvent(event);
(注意:傳遞自定義信息需要使用CustomEvent,而不是Event)
然后在監(jiān)聽(tīng)函數(shù)里取出:
document.addEventListener("myEvent",function(e){ console.log(e.dataName); })
以上就是“javascript怎么實(shí)現(xiàn)自定義事件功能”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。