[英]Simple event system using JavaScript (ES5) - JS Custom Event
說明:
提示:隨意擴展本機對象...盡管這通常是一種不好的做法。
// Start with an object, any object var myObject = {}; // Register an event on your object using // an `on` method myObject.on('myEvent', function(data) { // Log the data passed to the callback console.log(data); }); // Trigger the event using a `trigger` method. // Include some data when you trigger the event. myObject.trigger('myEvent', { company: 'ABC Corp', location: 'WTC Bangalore, IN', website: 'http://abc.co' }); // Register a different event myObject.on('yourEvent', function() { console.log('yourEvent fired'); }); // Trigger the new event myObject.trigger('yourEvent'); // Trigger all existing events using a special // "star" identifier. myObject.trigger('*'); // Remove one event by name myObject.off('myEvent'); // Since we've removed the event, this should // do nothing myObject.trigger('myEvent'); // Remove all existing events myObject.off(); // Since we've removed all events, this should // do nothing myObject.trigger('*');
其他一切進展順利。 實現myObject.trigger("*")
,我無法獲取“參數”; 實現"*"
時無法讀取參數對象/參數,因此拋出undefined
。
免責聲明我顯然不知道您上的是什么學校,但是請不要欺騙自己,以欺騙老師。 只需回答幾個簡單的問題,他們就會知道您是否了解這些材料,如果您出現一個很好的答案但不知道要備份什么,他們就會知道最新情況。 我不是在指責您,這只是對去年畢業后與老師有良好關系的人的友好建議;)
那么,我們該怎么做呢? 基本上,您至少必須在object
原型中添加一些功能,至少要使它影響此后制作的所有對象。 如果您只希望該類具有此功能,則可以始終創建自己的類並將功能添加到該原型中。
我們需要在原型on
添加3個功能,當然包括on
, off
和trigger
。 最重要的是,我們添加了一個名為events
額外屬性,最初是一個空對象。 您可以在jsfiddle中查看所有這些代碼的原始代碼,在這里我僅介紹代碼的結構和邏輯。
events
將保存與每個事件關聯的所有處理程序(函數)。 首次添加事件時,我們將eventName
屬性添加到events
對象,該屬性的值最初是一個空數組。
on
將在events
找到(或創建)鏈接到eventName
的數組,並將函數推入數組(注意,我們目前不調用函數,我們只是將對函數的引用存儲在數組中)。
off
將迭代eventName
的數組,如果找到相同的函數(請注意===
),則將其從數組中刪除。
trigger
將迭代eventName
的數組並調用每個函數。 請注意,使用設置為對象的函數中的this
關鍵字調用該函數,並使用與trigger
函數相同的參數來調用(eventName除外,第一個參數被濾除)。 是的,這意味着您可以傳遞任意數量的參數作為trigger(),它們將全部傳遞給每個處理程序。
我不會詳細介紹splice
, slice
, ===
, arguments
和apply
到底能做什么,我相信您可以在萬維網上的其他地方找到更多更好的信息。
您還可以做更多的事情,例如通過一些很好的作用域設置使events
對象不可見,但這不是問題的一部分,因此我對此並不在意。
瀏覽完此后,如果還有其他問題,請隨時提出。 我也沒有進行廣泛的測試,因此,如果您發現任何錯誤,請告訴我。
編輯:起初我沒有閱讀注釋,但是現在我還添加了對'*'通配符的支持。 基本上,這些函數現在會檢查通配符,並會在刪除或觸發時迭代event
對象上的所有eventName
。 您也可以通過不提供功能或提供相同的通配符但使用eventName來刪除事件的所有功能。
EDIT2:運行教師代碼時遇到了一些錯誤,意識到我忘記了在迭代時檢查hasOwnProperty
。 看一看,在處理原型時非常重要! 我現在在jsfiddle中輸入老師的代碼,向您展示它的工作原理:)
EDIT3-關於“未定義”日志。
老師的代碼調用了.trigger
5次,您應該看到4個控制台日志,據我所知, 它們都是正確的 。讓我遍歷每個觸發器以及隨后的控制台日志。
myEvent
添加一個處理程序,該處理程序記錄第一個參數 myEvent
,將記錄參數(對象)。 yourEvent
,該處理程序記錄一個硬編碼的字符串。 yourEvent
,沒有參數=>記錄了硬編碼的字符串' *
不帶參數 ,所有的處理程序運行=>未定義的登錄,因為沒有參數給出data
在myEvent
的處理程序是不確定的。 硬編碼的字符串也會被記錄 myEvent
處理程序,觸發myEvent
並確認未調用任何函數 *
並確認沒有任何事件調用任何函數。 老實說,我不知道您在步驟5會發生什么,因為您沒有提供任何參數,所以data
被分配為undefined
,這是預期的行為。
如果要合並步驟2中給出的數據,使其保留在對象上,請在處理程序中進行說明。 (例如,迭代data
所有屬性並將它們添加到this
,然后記錄this
)。 現在,您只需傳遞數據,就將其記錄下來,然后丟棄。 您還可以在步驟5中添加一個參數,然后所有處理程序都將接收該參數(包括yourEvent
處理程序,但該參數不會分配或使用它)。
document.getElementById("myBtn").addEventListener("click", displayDate);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.