JS模仿AS3事件机制

发布于 2022-09-03 23:23:28 字数 7302 浏览 17 评论 0

练习下自定义事件的实现,想让JS可以用AS3的语法使用自定义事件,实现很简单,因为没考虑复杂的情况吧。试过后发现有些地方还是模仿不了,最主要不一样的地方是:

1.侦听函数没法自动绑定那个函数所在的object,必须手动把object传进去,像这样:dispatcher.addEventListener(SampleDispatcher.ACTION, e.action, e);
最后还要传“e”这个obj进去,否则函数action里的this不指向e

2.使用的时候继承十分麻烦,还得小心翼翼,看demo就知道了。

  1. //事件发送者类
  2. var EventDispatcher = function() {
  3.         this.listeners = {};
  4. }
  5. EventDispatcher.prototype = {
  6.         addEventListener: function(type, fn, obj) {
  7.                 if (!fn) {
  8.                         throw new Error("function no found");
  9.                 }
  10.                 if (!this.listeners[type]) {
  11.                         this.listeners[type] = [];
  12.                 }
  13.                 var lis = this.listeners[type];
  14.                 if (!lis) {
  15.                         lis = [];
  16.                 }
  17.                 lis.push({"fn": fn, "obj": obj});
  18.         },
  19.         dispatchEvent: function(event) {
  20.                 var lis = this.listeners[event.type];
  21.                 if (lis && lis.length) {
  22.                         for (var i=0; i<lis.length; i++) {
  23.                                 event.target = this;
  24.                                 lis[i].fn.call(lis[i].obj, event)
  25.                         }
  26.                 }
  27.         },
  28.         removeEventListener: function(type, fn, obj) {
  29.                 var lis = this.listeners[type],
  30.                         ret = false;
  31.                 if (!lis) {
  32.                         return false;
  33.                 }
  34.                 for (var i=lis.length-1; i>-1; i--) {
  35.                         if (!fn || (lis[i].fn == fn && lis[i].obj == obj)) {
  36.                                 delete lis[i];
  37.                                 lis.splice(i, 1);
  38.                                 ret = true;
  39.                         }
  40.                 }
  41.                 if (!lis.length) {
  42.                         delete this.listeners[type];
  43.                 }
  44.                 return ret;
  45.         },
  46.         hasEventListener: function(type) {
  47.                 var lis = this.listeners[type]
  48.                 return lis && lis.length > 0 ? true: false;
  49.         }
  50. }
  51. //事件类
  52. var Event = function(type) {
  53.         this.type = type;
  54.         this.target = null;
  55. }
  56. Event.prototype = {
  57.         toString: function(){
  58.                 return this.type;
  59.         },
  60.         //clone功能未完善
  61.         clone: function(){
  62.                 return new Event(this.type);
  63.         }
  64. }

复制代码完全仿照《Actionscript3殿堂之路》里事件发送和处理的例子,写了个demo:

  1. //输出
  2. var trace = function(msg) {
  3.     document.write("<p>" + msg + "</p>");
  4. }
  5. //OrderEvent事件类
  6. var OrderEvent = function(type) {
  7.     OrderEvent.superclass.constructor.call(this, OrderEvent.ORDER_DISHES);
  8.     this.dishes = [];
  9. }
  10. YAHOO.extend(OrderEvent, Event);
  11. OrderEvent.ORDER_DISHES = "order";
  12. //服务生Waiter类
  13. var Waiter = function() {}
  14. Waiter.prototype.replyOrderFood = function(event) {
  15.     trace("你好," + event.target.name + "!你点的菜是:"+ event.dishes);
  16.     trace("我马上吩咐厨房去做");
  17. }
  18. //客人类Customer
  19. var Customer = function(name) {
  20.     Customer.superclass.constructor.call(this);
  21.     this.name = name;
  22. }
  23. YAHOO.extend(Customer, EventDispatcher);
  24. Customer.prototype.order = function(dishes) {
  25.     var orderDish = new OrderEvent();
  26.     orderDish.dishes = dishes? dishes: ["农家小炒", "麻婆豆腐", "烤鱿鱼"];
  27.     this.dispatchEvent(orderDish);
  28. }
  29. //生成客人和湘缘服务员
  30. var bang = new Customer("bang"),
  31.     xiangyuanWaiter = new Waiter();
  32. //注册侦听器,讲服务员的replyOrderFood()方法注册为侦听“order”事件的侦听器
  33. bang.addEventListener(OrderEvent.ORDER_DISHES, xiangyuanWaiter.replyOrderFood, xiangyuanWaiter);
  34. //俺点菜了,菜单在俺这个类里面
  35. bang.order();
  36. //再点次菜,点些饮料
  37. bang.order(["鸡尾酒","咖啡"]);
  38. //吃完饭,移除侦听器
  39. bang.removeEventListener(OrderEvent.ORDER_DISHES, xiangyuanWaiter.replyOrderFood, xiangyuanWaiter);

复制代码

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文