使用JavaScript(ES5) - JS自定义事件的简单事件系统 [英] Simple event system using JavaScript (ES5) - JS Custom Event

查看:366
本文介绍了使用JavaScript(ES5) - JS自定义事件的简单事件系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说明:


  1. 使此代码无需修改代码即可。

  2. 仅使用纯旧的JavaScript和没有第三方库。

  3. 编写新的代码,使以下代码正常工作。

提示:随意扩展本机对象,即使通常是一个糟糕的做法。



  //从一个对象开始,任何objectvar myObject = {}; //使用一个`on` methodmyObject.on('myEvent',function(data){//记录数据)在对象上注册一个事件传递给回调console.log(data);}); //使用`trigger`方法触发事件//在触发event.myObject.trigger时包含一些数据('myEvent',{company:'ABC公司,位置:'WTC Bangalore,IN',网站:'http:// ab c.co}); //注册一个不同的eventmyObject.on('yourEvent',function(){console.log('yourEvent fired');}); //触发新的eventmyObject.trigger('yourEvent'); //触发所有现有事件使用一个特殊的//staridentifier.myObject.trigger('*'); //通过namemyObject.off('myEvent')删除一个事件; //因为我们已经删除了这个事件, .trigger('myEvent'); //删除所有现有的事件myObject.off(); //因为我们已经删除了所有的事件,所以应该做任何事情,而不是mymy.trigger('*');  



其他一切顺利。实现 myObject.trigger(*)时,我无法获取参数;在实现*时无法读取参数对象/参数,因此抛出 undefined



我的JSFiddle

解决方案

免责声明
我显然不知道你去哪所学校或任何东西,但请不要愚弄自己试图愚弄你的老师有几个简单的问题,他们会知道,如果你了解材料,而不是,如果你出现了一个很好的答案,但没有知识支持,他们会知道是什么。我不是指责你,只是一个友好的建议,一个与他的老师在去年毕业后有良好关系的建议;)



那么我们该怎么做呢?基本上,您将不得不向对象的原型添加一些功能,至少如果您希望此功能影响之后制作的所有对象。您可以随时创建自己的类,并将功能添加到该原型,如果您只希望该类具有此功能。



我们需要3个功能添加到原型,当然,code> on , off trigger 此外,我们还添加了一个名为 events 的额外属性,最初是一个空对象。
您可以在jsfiddle中查看所有这些的原始代码,我将只在这里查看代码的结构和逻辑。



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



on 将找到(或创建)链接到 eventName 事件中,并将该函数推入数组(请注意,我们此时不调用该函数,只需将引用存储到数组中的函数)



off 将遍历 eventName ,如果它找到相同的功能(注意 === ),将其从数组中删除。



触发器将迭代数组 eventName 并调用每个函数。请注意,在设置为对象的函数中使用关键字调用该函数,并且具有与触发器相同的参数函数被调用(除了eventName,第一个参数,被过滤掉)。是的,这意味着你可以传递尽可能多的参数来触发(),并将它们都传递给每个处理程序。



我不会详细说明什么像 splice slice === 参数应用完全确定,我相信你可以找到更多更好的信息,在世界各地的其他地方。



还有更多的你可以做到这一点,就像使的事件对象不可见通过一些很好的使用范围界定,但这不是问题的一部分,所以我没有打扰。



如果您在查看后再回答问题,请随时问。我也没有广泛测试,所以如果你发现任何错误,让我知道。



编辑:我没有首先阅读评论,但我现在还增加了对'*'通配符的支持。基本上,这些功能现在检查通配符,并且在删除或触发时将重复事件对象的所有 eventName 。您还可以通过不给出功能或通过给出相同的通配符,但是使用eventName来删除事件的所有功能。



EDIT2:有一些错误运行老师的代码,意识到我忘了在迭代时检查 hasOwnProperty 。看一下,在使用原型时非常重要!
我现在把jsfiddle中的老师的代码放在这里,告诉你它的工作原理:)



jsfiddle与自己的代码



jsfiddle与老师代码



EDIT3 - 关于'未定义'日志。



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


  1. 您将一个处理程序添加到 myEvent ,其中记录第一个参数

  2. 您触发 myEvent 参数 =>参数(对象)是
    记录。

  3. 您将一个处理程序添加到 yourEvent 中,该日志记录了硬编码的
    字符串。

  4. <您触发 yourEvent ,no parameter =>硬编码字符串被记录'
  5. 您触发 * 没有参数,所有处理程序run => undefined都被记录,因为没有给出参数,数据 myEvent 的处理程序未定义。硬编码的字符串也被记录

  6. 您删除 myEvent 处理程序,触发 myEvent 并确认没有函数调用

  7. 您删除所有事件处理程序,触发 * 并确认没有从任何事件调用的函数。 / li>

我真的不知道你在第5步中会发生什么,因为你没有参数,数据被分配未定义,这是行为。



如果要合并数据在步骤2中给出,所以它保留在对象上,然后在你的处理程序中指示。 (例如,迭代数据的所有属性,并将它们添加到,然后记录 )。现在你只需传递它的数据,它被记录,然后丢弃。您还可以在步骤5中添加一个参数,然后所有处理程序都将收到它(包括 yourEvent 处理程序,但不分配也不使用它)。 p>

Instructions:

  1. make this code work without modifying snippet it in any way.
  2. Use only plain old JavaScript and no third-party libraries.
  3. Write new code that enables the code below to work properly.

Hint: Feel free to extend native objects... even though it's typically a bad practice.

// 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('*');

Everything else went well. I'm unable to get "arguments" while implementing myObject.trigger("*"); unable to read arguments object / parameters while implementing "*" and hence throw undefined.

My JSFiddle

解决方案

Disclaimer I obviously dont know what school you go to or anything, but please don't fool yourself trying to fool your teachers. With a few simple questions they'll know if you understand the material or not, and if you show up with a good answer but no knowledge to back it up, they will know what's up. I'm not accusing you of this, just a friendly word of advice of someone who has had good connections with his teachers after graduating last year ;)

So, how do we do this? Basically, you will have to add some functionality to the prototype of object, at least if you want this to affect all objects made afterwards. You can always create your own class and add the function to that prototype if you only want that class to have this functionality.

We need 3 functions added to the prototype, on, off and trigger of course. On top of that we add one extra property called events, initially an empty object. You can look at the raw code for all these in the jsfiddle, I will only go through the structure and logic of the code here.

events will hold all the handlers (functions) associated with each event. When adding an event for the first time, we add a eventName property to the events object, the value for this property is initially an empty array.

on will find (or create) the array linked to eventName in events, and push the function into the array (note we do not call the function at this time, we simply store the reference to the function in the array).

off will iterate the array of eventName, and if it finds the same function (note the ===), remove it from the array.

trigger will iterate the array of eventName and call each function. Note that the function is called with the this keyword in the function set to the object, and with the same parameters as the trigger function was called (except eventName, the first parameter, which is filtered out). Yes that means you can pass as many parameters as you want to trigger(), and they will all be passed to each handler.

I won't go into detail what things like splice, slice, ===, arguments and apply do exactly, I'm sure you can find more and better information about that elsewhere on the world wide interwebs.

There's a lot more you can do for this, like making the events object invisible through some nice uses of scoping, but that wasn't part of the question so I didn't bother with that.

If you have any more questions after looking through this, feel free to ask. I also didn't test it extensively so if you find any bugs, let me know.

EDIT: I didn't read through the comments at first, but I now also added support for the '*' wildcard. Basically the functions now check for the wildcard and will iterate all eventNames on the event object when removing or triggering. You can also remove all functions for an event by not giving a function or by giving the same wildcard, but with an eventName.

EDIT2: had some bugs running the teacher's code, realized I forgot to check for hasOwnProperty while iterating. Look that one up, it's very important when working with prototypes! I now put in the teacher's code in my jsfiddle, to show you that it works :)

jsfiddle with own code

jsfiddle with teacher code

EDIT3 - about the 'undefined' log.

The teacher's code calls .trigger 5 times, and you should see 4 console logs and as far as I can tell, they are all correct.Let me run through each trigger, and the subsequent console logs.

  1. You add a handler to myEvent, which logs the first parameter
  2. You trigger myEvent, with parameter => The parameter (the object), is logged.
  3. You add a handler to yourEvent, which logs a hardcoded string.
  4. You trigger yourEvent, no parameter => The hardcoded string is logged'
  5. You trigger * with no parameter, all handlers run => undefined is logged, since no parameters were given, data in myEvent's handler is undefined. The hardcoded string is also logged
  6. You remove the myEvent handler, trigger myEvent and confirm no functions are called
  7. You remove all event handlers, trigger * and confirm no functions are called from any events.

I honestly don't know what you expected to happen on step 5, since you give no parameter, the data is assigned undefined, that's intended behaviour.

If you want to merge the data given in step 2 so it remains on the object, then instruct so in your handler. (for example, iterate all properties of data and add them to this, then log this). Right now you simply pass it data, it gets logged, and then thrown away. You can also add a parameter in step 5, and then all handlers will receive it (including the yourEvent handlers, but that one doesn't assign nor use it).

这篇关于使用JavaScript(ES5) - JS自定义事件的简单事件系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆