js自定義事件及事件交互原理概述(二)
1、此事件對(duì)象只能注冊(cè)一個(gè)事件,不能提供多個(gè)事件
2、注冊(cè)方法沒(méi)有返回的一些信息
下面我們就來(lái)解決這些問(wèn)題。如下為MyEvent.js源代碼:
function MyEvent(){
this.handlers={};
}
MyEvent.prototype={
addHandler:function(type,handler)
{
if(typeof this.handlers[type]=="undefined")
{
this.handlers[type]=[];
}
this.handlers[type].push(handler);
},
fire:function(event)
{if(this.handlers[event.type] instanceof Array)
{
var handlers=this.handlers[event.type];
for(var i= 0, len=handlers.length;i<len;i++)
{
handlers[i](event);
}
}
},
removeHandler:function(type,handler)
{
if(this.handlers[type] instanceof Array)
{
var handlers=this.handlers[type];
for(var i= 0, len=handlers.length;i<len;i++)
{
if(handlers[i]===handler)
{
break;
}
}
handlers.splice(i,1);
}
}
};
此類就是對(duì)第一篇的優(yōu)化。
屬性handler變成了handlers,變成了一個(gè)數(shù)組
addHandler()方法接受兩個(gè)參數(shù):事件類型和用于處理該事件的函數(shù)。當(dāng)調(diào)用該方法時(shí),會(huì)進(jìn)行一次檢查,看看handlers屬性中是否已經(jīng)存在一個(gè)針對(duì)該事件類型的數(shù)組
;如果沒(méi)有,則創(chuàng)建一個(gè)新的。然后使用push()將該處理程序添加到數(shù)組的末尾。
fire()方法用于觸發(fā)一個(gè)事件,該方法接受一個(gè)參數(shù),是一個(gè)至少包含type屬性的對(duì)象,不然無(wú)法確定handlers里面是否已經(jīng)存在。它會(huì)通過(guò)此type去查找對(duì)應(yīng)該事件類型的一組處理程序,調(diào)用各個(gè)函數(shù),并給出event對(duì)象。因?yàn)檫@些都是自定義對(duì)象,所以event對(duì)象上面的其他東西可以由你自己定義。
removeHandler()方法時(shí)addHandler()的輔助,它們接受的參數(shù)一樣:事件的類型和事件處理程序。這個(gè)方法搜索事件處理程序的數(shù)組找到要?jiǎng)h除的處理程序的位置。如果找到了,則使用break操作符退出循環(huán)。然后使用splice()方法將該項(xiàng)目從數(shù)組中刪除。
這里使用方式我們換一種比較長(zhǎng)用的形式,現(xiàn)在據(jù)我說(shuō)知很多產(chǎn)品在使用事件上有兩種方式,一種是直接繼承(js本省沒(méi)有此概念,不過(guò)我們可以通過(guò)原型鏈模擬出繼承的效果,此處不做詳細(xì)解釋)此事件對(duì)象,那么就會(huì)擁有了這些行為,不過(guò)此方法比較局限,另一種方式更常用一些,就是需要使用事件的類上面創(chuàng)建一個(gè)屬性用于存放此對(duì)象。如:子相同目錄下再創(chuàng)建一個(gè)Student.js文件,里面的代碼如下:
function Student(name)
{
this.myEvent=new MyEvent();
this.name=name;
}
Student.prototype={
setName:function(name)
{
var eventStart={
type:"changeNameStart",
newName:name,
oldName:this.name
};
this.myEvent.fire(eventStart);
this.name=name;
}
}
這里有一個(gè)學(xué)生類,構(gòu)造函數(shù)里面初始化一個(gè)MyEvent對(duì)象作為屬性,通過(guò)參數(shù)初始化name屬性。
提供一個(gè)方法setName用于改變名字,不過(guò)在改變名字之前設(shè)置了可能觸發(fā)事件changNameStart的監(jiān)聽(tīng)。
創(chuàng)建一個(gè)html頁(yè)面,放于同個(gè)目錄下,代碼如下:
<html>
<head>
<title></title>
<script type="text/javascript" src="MyEvent.js"></script>
<script type="text/javascript" src="Student.js"></script>
<script type="text/javascript">
function init()
{
//初始化一個(gè)學(xué)生對(duì)象
var student=new Student("Mr liu");
//注冊(cè)事件changNameStart
student.myEvent.addHandler("changeNameStart",myMethod);
//設(shè)置name,將會(huì)觸發(fā)事件changNameStart
student.setName("Mr Huang");
}
function myMethod(e)
{
alert("事件類型:"+e.type+"; 改變前的名字:"+ e.oldName+"; 改變后的名字:"+ e.newName);
}
</script>
</head>
<body>
<input type="button" onclick="init()" value="測(cè)試" />
</body>
</html>
這樣使用起來(lái)就會(huì)很方便,也是一種常用的使用方式。
一般在真正的項(xiàng)目里面使用使用事件時(shí)我們還需要做一些優(yōu)化,比如:
1、用戶并不知道我們提供了哪些事件,從代碼來(lái)看好像什么事件都可以添加到handlers里面,但是真正起效果的(我們?cè)O(shè)置fire()方法的地方)事件我們并不能從代碼里面很直觀的看出來(lái),一般做產(chǎn)品,在這方面都需要再做考慮。
2、有沒(méi)有發(fā)現(xiàn)fire的參數(shù)event好像沒(méi)用固定,在大興項(xiàng)目里面,最好event也做成一個(gè)類型,在fire的地方就比較方便使用一些,event可能會(huì)有很多種類型,那時(shí)可能fire里面會(huì)出現(xiàn)一些判定了。
希望對(duì)初入js事件的讀者有所幫助,互相交流。
相關(guān)文章
使用?JavaScript?Promise?讀取?Github?用戶數(shù)據(jù)
這篇文章主要介紹了使用JavaScript?Promise讀取Github用戶數(shù)據(jù),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08
微信小程序?qū)崿F(xiàn)時(shí)間預(yù)約功能
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)時(shí)間預(yù)約基本功能,一個(gè)類似電商的時(shí)間預(yù)約功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
基于JavaScript實(shí)現(xiàn)前端文件的斷點(diǎn)續(xù)傳
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)前端文件的斷點(diǎn)續(xù)傳的相關(guān)資料,需要的朋友可以參考下2016-10-10
uniapp小程序項(xiàng)目獲取位置經(jīng)緯度信息
在實(shí)際項(xiàng)目中很多時(shí)候我們需要獲取設(shè)備的位置信息,去展示給客戶,或者以位置信息為參數(shù),繼續(xù)向服務(wù)器獲取一些數(shù)據(jù),這篇文章主要介紹了uni-app如何獲取位置信息(經(jīng)緯度),需要的朋友可以參考下2022-11-11
JS實(shí)現(xiàn)的DIV塊來(lái)回滾動(dòng)效果示例
這篇文章主要介紹了JS實(shí)現(xiàn)的DIV塊來(lái)回滾動(dòng)效果,結(jié)合實(shí)例形式分析了JS通過(guò)時(shí)間函數(shù)定時(shí)觸發(fā)動(dòng)態(tài)改變頁(yè)面元素樣式的相關(guān)操作技巧,需要的朋友可以參考下2017-02-02
微信小程序+mqtt,esp8266溫濕度讀取的實(shí)現(xiàn)方法
這篇文章主要介紹了微信小程序+mqtt,esp8266溫濕度讀取的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
javascript 漢字轉(zhuǎn)拼音實(shí)現(xiàn)代碼
主要是提前定義了很多文字,這樣的方法不是很是,如果庫(kù)中沒(méi)有這個(gè)詞,是看不到相關(guān)信息的。2009-12-12
JavaScript callback回調(diào)函數(shù)用法實(shí)例分析
這篇文章主要介紹了JavaScript callback回調(diào)函數(shù)用法,結(jié)合實(shí)例形式分析了callback回調(diào)函數(shù)的概念、功能、應(yīng)用場(chǎng)景及相關(guān)使用技巧,需要的朋友可以參考下2018-05-05
TypeScript中d.ts類型聲明文件的實(shí)現(xiàn)
.d.ts 文件是 TypeScript 的類型聲明文件,它們的主要作用是為 JavaScript 庫(kù)提供類型支持,本文主要介紹了TypeScript中d.ts類型聲明文件的實(shí)現(xiàn),感興趣的可以了解一下2023-10-10

