使用 JavaScript 的简单事件系统 (ES5) - JS 自定义事件



>说明:

  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

My JSFiddle

免责声明我显然不知道你上什么学校或什么,但请不要欺骗自己试图愚弄你的老师。通过几个简单的问题,他们就会知道你是否理解材料,如果你出现一个很好的答案但没有知识来支持它,他们就会知道发生了什么。我不是在指责你,只是对去年毕业后与老师有良好关系的人的友好建议;)

那么,我们如何做到这一点呢?基本上,您必须添加一些功能 object原型 ,至少如果您希望这影响之后制作的所有对象。如果您只希望该类具有此功能,则始终可以创建自己的类并将函数添加到该原型中。

我们需要在原型中添加 3 个功能,on ,当然是offtrigger。最重要的是,我们添加了一个名为 events ,最初是一个空对象。您可以在 jsfiddle 中查看所有这些的原始代码,我在这里只介绍代码的结构和逻辑。

events将保存与每个事件关联的所有处理程序(函数(。第一次添加事件时,我们向events对象添加一个 eventName 属性,此属性的值最初是一个空数组。

on 将在 events 中找到(或创建(链接到eventName的数组,并将函数推送到数组中(注意我们此时不调用函数,我们只是将对函数的引用存储在数组中(。

off将迭代eventName数组,如果它找到相同的函数(注意===(,则将其从数组中删除。

trigger将迭代eventName数组并调用每个函数。请注意,该函数是使用设置为对象的函数中的 this 关键字调用的,并且使用与调用trigger函数相同的参数(第一个参数 eventName 除外,它被过滤掉(。是的,这意味着您可以传递任意数量的参数 trigger((,并且它们都将传递给每个处理程序。

我不会详细介绍像spliceslice===argumentsapply之类的事情,我相信你可以在万维网的其他地方找到更多更好的信息。

为此,您可以做更多的事情,例如通过一些很好的范围使用使events对象不可见,但这不是问题的一部分,所以我没有为此烦恼。

如果您在阅读本文后还有其他问题,请随时提问。我也没有对其进行广泛的测试,所以如果您发现任何错误,请告诉我。

编辑:起初我没有通读评论,但现在我还添加了对"*"通配符的支持。基本上,函数现在检查通配符,并在删除或触发时迭代event对象上的所有eventName。您还可以通过不给出函数或提供相同的通配符但使用 eventName 来删除事件的所有函数。

EDIT2:运行老师的代码时有一些错误,意识到我在迭代时忘记检查hasOwnProperty。看看那个,在使用原型时非常重要!我现在在我的jsfiddle中输入了老师的代码,以向您展示它的工作原理:)

JSFIDDLE 与自己的代码

JSFIDDLE 与教师代码

编辑3 - 关于"未定义"日志。

老师的代码调用.trigger 5 次,您应该会看到 4 个控制台日志,据我所知,它们都是正确的。让我运行每个触发器和后续控制台日志。

  1. 将处理程序添加到 myEvent ,该处理程序记录第一个参数
  2. 触发 myEvent参数 => 参数(对象(为登录。
  3. 将处理程序添加到 yourEvent ,这将记录硬编码字符串。
  4. 你触发yourEvent,没有参数=>记录硬编码的字符串'
  5. 您触发*没有参数,所有处理程序运行 => 未定义被记录,因为没有给出参数,data myEvent 的处理程序是未定义的。还会记录硬编码字符串
  6. 删除myEvent处理程序,触发myEvent并确认未调用任何函数
  7. 删除所有事件处理程序,触发*并确认没有从任何事件调用任何函数。

老实说,我不知道您希望在步骤5上发生什么,因为您没有给出参数,data被分配undefined,这是预期的行为。

如果要合并步骤 2 中给出的数据,使其保留在对象上,请在处理程序中指示。(例如,迭代data的所有属性并将它们添加到 this ,然后记录this (。现在你只需传递它数据,它就会被记录下来,然后扔掉。您还可以在步骤 5 中添加参数,然后所有处理程序都将收到它(包括yourEvent处理程序,但该处理程序不会分配或使用它(。

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

相关内容

  • 没有找到相关文章