欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

js自定義事件及事件交互原理概述(二)

 更新時(shí)間:2013年02月01日 14:12:53   作者:  
上一篇的目的只是讓大家簡(jiǎn)單的理解自定事件是如何模擬出來(lái)的,大家不難發(fā)現(xiàn)會(huì)有很多缺陷,本篇主要已解決上一篇的問(wèn)題為主,感興趣的朋友可以參考,或許本文對(duì)你有所幫助
js自定義事件(一)的目的只是讓大家簡(jiǎn)單的理解自定事件是如何模擬出來(lái)的,大家不難發(fā)現(xiàn)會(huì)有很多缺陷,比如:
1、此事件對(duì)象只能注冊(cè)一個(gè)事件,不能提供多個(gè)事件
2、注冊(cè)方法沒(méi)有返回的一些信息

下面我們就來(lái)解決這些問(wèn)題。如下為MyEvent.js源代碼:
復(fù)制代碼 代碼如下:

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文件,里面的代碼如下:
復(fù)制代碼 代碼如下:

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è)目錄下,代碼如下:
復(fù)制代碼 代碼如下:

<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)文章

最新評(píng)論