簡體   English   中英

使用JavaScript(ES5)的簡單事件系統-JS自定義事件

[英]Simple event system using JavaScript (ES5) - JS Custom Event

說明:

  1. 使此代碼有效,而無需以任何方式修改代碼段。
  2. 僅使用普通的舊JavaScript,而不使用第三方庫。
  3. 編寫新代碼,使下面的代碼正常工作。

提示:隨意擴展本機對象...盡管這通常是一種不好的做法。

 // 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

我的JSFiddle

免責聲明我顯然不知道您上的是什么學校,但是請不要欺騙自己,以欺騙老師。 只需回答幾個簡單的問題,他們就會知道您是否了解這些材料,如果您出現一個很好的答案但不知道要備份什么,他們就會知道最新情況。 我不是在指責您,這只是對去年畢業后與老師有良好關系的人的友好建議;)

那么,我們該怎么做呢? 基本上,您至少必須在object原型中添加一些功能,至少要使它影響此后制作的所有對象。 如果您只希望該類具有此功能,則可以始終創建自己的類並將功能添加到該原型中。

我們需要在原型on添加3個功能,當然包括onofftrigger 最重要的是,我們添加了一個名為events額外屬性,最初是一個空對象。 您可以在jsfiddle中查看所有這些代碼的原始代碼,在這里我僅介紹代碼的結構和邏輯。

events將保存與每個事件關聯的所有處理程序(函數)。 首次添加事件時,我們將eventName屬性添加到events對象,該屬性的值最初是一個空數組。

on將在events找到(或創建)鏈接到eventName的數組,並將函數推入數組(注意,我們目前不調用函數,我們只是將對函數的引用存儲在數組中)。

off將迭代eventName的數組,如果找到相同的函數(請注意=== ),則將其從數組中刪除。

trigger將迭代eventName的數組並調用每個函數。 請注意,使用設置為對象的函數中的this關鍵字調用該函數,並使用與trigger函數相同的參數來調用(eventName除外,第一個參數被濾除)。 是的,這意味着您可以傳遞任意數量的參數作為trigger(),它們將全部傳遞給每個處理程序。

我不會詳細介紹spliceslice===argumentsapply到底能做什么,我相信您可以在萬維網上的其他地方找到更多更好的信息。

您還可以做更多的事情,例如通過一些很好的作用域設置使events對象不可見,但這不是問題的一部分,因此我對此並不在意。

瀏覽完此后,如果還有其他問題,請隨時提出。 我也沒有進行廣泛的測試,因此,如果您發現任何錯誤,請告訴我。

編輯:起初我沒有閱讀注釋,但是現在我還添加了對'*'通配符的支持。 基本上,這些函數現在會檢查通配符,並會在刪除或觸發時迭代event對象上的所有eventName 您也可以通過不提供功能或提供相同的通配符但使用eventName來刪除事件的所有功能。

EDIT2:運行教師代碼時遇到了一些錯誤,意識到我忘記了在迭代時檢查hasOwnProperty 看一看,在處理原型時非常重要! 我現在在jsfiddle中輸入老師的代碼,向您展示它的工作原理:)

jsfiddle與自己的代碼

jsfiddle與老師代碼

EDIT3-關於“未定義”日志。

老師的代碼調用了.trigger 5次,您應該看到4個控制台日志,據我所知, 它們都是正確的 。讓我遍歷每個觸發器以及隨后的控制台日志。

  1. 您向myEvent添加一個處理程序,該處理程序記錄第一個參數
  2. 使用參數 =>觸發myEvent ,將記錄參數(對象)。
  3. 您將一個處理程序添加到yourEvent ,該處理程序記錄一個硬編碼的字符串。
  4. 您觸發yourEvent ,沒有參數=>記錄了硬編碼的字符串'
  5. 你觸發* 不帶參數 ,所有的處理程序運行=>未定義的登錄,因為沒有參數給出datamyEvent的處理程序是不確定的。 硬編碼的字符串也會被記錄
  6. 您刪除myEvent處理程序,觸發myEvent並確認未調用任何函數
  7. 您刪除所有事件處理程序,觸發*並確認沒有任何事件調用任何函數。

老實說,我不知道您在步驟5會發生什么,因為您沒有提供任何參數,所以data被分配為undefined ,這是預期的行為。

如果要合並步驟2中給出的數據,使其保留在對象上,請在處理程序中進行說明。 (例如,迭代data所有屬性並將它們添加到this ,然后記錄this )。 現在,您只需傳遞數據,就將其記錄下來,然后丟棄。 您還可以在步驟5中添加一個參數,然后所有處理程序都將接收該參數(包括yourEvent處理程序,但該參數不會分配或使用它)。

document.getElementById("myBtn").addEventListener("click", displayDate);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM