如何动态注册到jquery自定义事件?

时间:2021-07-18 23:55:05

I have built a dom object Engine that has private/public fields/methods that I have simplified below:

我已经构建了一个dom对象引擎,它具有我在下面简化的私有/公共字段/方法:

function Engine(args){
   this.display = args.display;

   this.getDisplay = function(){return this.display;}
   this.alertMsg = function(msg){
      console.log(this.display);
      alert(msg);
   }
}

What I would like to do is build a custom event that would be triggered after the alert(msg) such as $(this.display).trigger("afterAlert");

我想要做的是构建一个自定义事件,该事件将在警报(msg)之后触发,例如$(this.display).trigger(“afterAlert”);

function Engine(args){
   this.display = args.display;

   this.getDisplay = function(){return this.display;}
   this.alertMsg = function(msg){
      console.log(this.display);
      alert(msg);
      // trigger custom event here
      $(this.display).trigger("afterAlert");
   }
}

Now, this event could be empty or not. How would one or more objects declared later register to the "afterAlert" event? In my case, additional javascript files are loaded by the main file dynamically and could contain a code ressembling :

现在,这个事件可能是空的或不是。稍后声明的一个或多个对象如何注册到“afterAlert”事件?在我的情况下,主文件动态加载其他javascript文件,可能包含重新代码的代码:

function new_obj(){
    bind("afterAlert", function(){
       alert("alert was called");
    });
}

2 个解决方案

#1


4  

See my answer from this question...repeated for clarity

从这个问题看我的答案...为了清楚起见重复

I will tackle the register, triggering and unbinding of custom events.

我将解决注册,触发和解除自定义事件的问题。

jQuery has all the tools you need to register, bind and unbind to custom events.

jQuery具有注册,绑定和解除绑定到自定义事件所需的所有工具。

Below is an example of hooking up two divs to a custom event called customAjaxStart. I can then trigger this function and both handlers will get called.

下面是一个将两个div连接到名为customAjaxStart的自定义事件的示例。然后我可以触发这个函数,两个处理程序都会被调用。

Quick Demo Here - Have the firebug/ie8 console enabled.

快速演示 - 启用firebug / ie8控制台。

e.g

$( function() {

  $('#div1').bind('customAjaxStart', function(){
    console.log('#div1 ajax start fired');
    $(this).fadeTo('slow', 0.3);
  });

  $('#div2').bind('customAjaxStart', function(){
    console.log('#div1 ajax start fired');
    $(this).fadeTo('slow', 0.3);
  });

  //fire the custom event
  $.event.trigger('customAjaxStart');

  //unbind div1 from custom event
  $('#div1').unbind('customAjaxStart');

  //again trigger custom event - div1 handler will not fire this time
 $.event.trigger('customAjaxStart'); 
});

Taking the above as an example I would trigger the customAjaxStart from the global ajaxStart. Any listeners would be triggered automatically whenever an xhr call is about to be made (ideal for disabling your widgets or showing a loading gif etc) e.g

以上面为例,我将从全局ajaxStart触发customAjaxStart。无论何时进行xhr调用,都会自动触发任何侦听器(非常适合禁用小部件或显示加载gif等),例如

$.ajaxStart( function(){

    $.event.trigger('customAjaxStart');

});

#2


2  

I think what you are looking for is the Observer pattern. At least that's how I would implement it. The following code snippet uses different names but it does essentially what you want (allows registering for events, and even triggering):

我认为你要找的是观察者模式。至少我是如何实现它的。以下代码片段使用不同的名称,但它基本上可以实现您所需的功能(允许注册事件,甚至触发):

    Observable = {
  addObserver: function(observer) {
    if (!this.__observers) this.__observers = [];
    this.__observers.push(observer);
  },
  addGlobalObserver: function(observer) {
    if (!this.__global_observers) this.__global_observers = [];
    this.__global_observers.push(observer);
  },
  removeObserver: function(observer) {
    var newObservers = [];
    var co;
    while (co = this.__observers.pop()) {
      if (co != observer) newObservers.push(co)
    }
    this.__observers = newObservers;
    newObservers = [];
    while (co = this.__global_observers.pop()) {
      if (co != observer) newObservers.push(co)
    }
    this.__global_observers = newObservers;
  },
  notify: function(event) {
    var allObservers = this.__global_observers.concat(this.__observers);
    for (var i=0; i < allObservers.length; i++) {
      var o = allObservers[i];
      if (o[event]) {
        var args = []
        for (var j=1; j < arguments.length; j++) {
          args.push(arguments[j])
        };
        o[event].apply(this, args);
      }
    };
  },
  __global_observers: [],
  __initializer: function() {
    this.__observers = [];
  }
};

If you include this code into your class, you can register for events using addObserver() (addGlobalObserver() for "class level" events). Inside the object you trigger an event using notify().

如果将此代码包含在类中,则可以使用addObserver()(addGlobalObserver()为“类级别”事件)注册事件。在对象内部,您使用notify()触发事件。

Code taken from Coltrane.

代码取自Coltrane。

#1


4  

See my answer from this question...repeated for clarity

从这个问题看我的答案...为了清楚起见重复

I will tackle the register, triggering and unbinding of custom events.

我将解决注册,触发和解除自定义事件的问题。

jQuery has all the tools you need to register, bind and unbind to custom events.

jQuery具有注册,绑定和解除绑定到自定义事件所需的所有工具。

Below is an example of hooking up two divs to a custom event called customAjaxStart. I can then trigger this function and both handlers will get called.

下面是一个将两个div连接到名为customAjaxStart的自定义事件的示例。然后我可以触发这个函数,两个处理程序都会被调用。

Quick Demo Here - Have the firebug/ie8 console enabled.

快速演示 - 启用firebug / ie8控制台。

e.g

$( function() {

  $('#div1').bind('customAjaxStart', function(){
    console.log('#div1 ajax start fired');
    $(this).fadeTo('slow', 0.3);
  });

  $('#div2').bind('customAjaxStart', function(){
    console.log('#div1 ajax start fired');
    $(this).fadeTo('slow', 0.3);
  });

  //fire the custom event
  $.event.trigger('customAjaxStart');

  //unbind div1 from custom event
  $('#div1').unbind('customAjaxStart');

  //again trigger custom event - div1 handler will not fire this time
 $.event.trigger('customAjaxStart'); 
});

Taking the above as an example I would trigger the customAjaxStart from the global ajaxStart. Any listeners would be triggered automatically whenever an xhr call is about to be made (ideal for disabling your widgets or showing a loading gif etc) e.g

以上面为例,我将从全局ajaxStart触发customAjaxStart。无论何时进行xhr调用,都会自动触发任何侦听器(非常适合禁用小部件或显示加载gif等),例如

$.ajaxStart( function(){

    $.event.trigger('customAjaxStart');

});

#2


2  

I think what you are looking for is the Observer pattern. At least that's how I would implement it. The following code snippet uses different names but it does essentially what you want (allows registering for events, and even triggering):

我认为你要找的是观察者模式。至少我是如何实现它的。以下代码片段使用不同的名称,但它基本上可以实现您所需的功能(允许注册事件,甚至触发):

    Observable = {
  addObserver: function(observer) {
    if (!this.__observers) this.__observers = [];
    this.__observers.push(observer);
  },
  addGlobalObserver: function(observer) {
    if (!this.__global_observers) this.__global_observers = [];
    this.__global_observers.push(observer);
  },
  removeObserver: function(observer) {
    var newObservers = [];
    var co;
    while (co = this.__observers.pop()) {
      if (co != observer) newObservers.push(co)
    }
    this.__observers = newObservers;
    newObservers = [];
    while (co = this.__global_observers.pop()) {
      if (co != observer) newObservers.push(co)
    }
    this.__global_observers = newObservers;
  },
  notify: function(event) {
    var allObservers = this.__global_observers.concat(this.__observers);
    for (var i=0; i < allObservers.length; i++) {
      var o = allObservers[i];
      if (o[event]) {
        var args = []
        for (var j=1; j < arguments.length; j++) {
          args.push(arguments[j])
        };
        o[event].apply(this, args);
      }
    };
  },
  __global_observers: [],
  __initializer: function() {
    this.__observers = [];
  }
};

If you include this code into your class, you can register for events using addObserver() (addGlobalObserver() for "class level" events). Inside the object you trigger an event using notify().

如果将此代码包含在类中,则可以使用addObserver()(addGlobalObserver()为“类级别”事件)注册事件。在对象内部,您使用notify()触发事件。

Code taken from Coltrane.

代码取自Coltrane。