jQuery中的自定义事件?

我正在寻找一些关于如何在jQuery中实现自定义事件处理的最佳方法的input。 我知道如何连接像'点击'等DOM元素事件,但我build立一个小的JavaScript库/插件来处理一些预览function。

我有一个脚本运行,从一组规则和数据/用户input中更新dom元素中的某些文本,但是现在我需要显示其他元素中显示的相同文本,该脚本不可能知道这些文本。 我需要的是一个很好的模式,以某种方式观察这个脚本产生所需的文字。

那我该怎么做呢? 我忽略了jQuery中的一些内置function来提升/处理用户事件,还是我需要一些jquery插件来做到这一点? 你认为最好的方式/插件来处理这个问题?

看看这个:

(转载自http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/,基于http://web.archive.org/web上的存档版本/20130120010146/http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/


用jQuery发布/订阅

2008年6月17日

为了编写一个集成了Google Gears离线function的jQuery UI,我一直在用一些代码来使用jQuery来轮询networking连接状态。

networking检测对象

基本前提非常简单。 我们创build一个networking检测对象的实例,它将定期轮询一个URL。 如果这些HTTP请求失败,我们可以假定networking连接已经丢失,或者服务器在当前时间是无法访问的。

$.networkDetection = function(url,interval){ var url = url; var interval = interval; online = false; this.StartPolling = function(){ this.StopPolling(); this.timer = setInterval(poll, interval); }; this.StopPolling = function(){ clearInterval(this.timer); }; this.setPollInterval= function(i) { interval = i; }; this.getOnlineStatus = function(){ return online; }; function poll() { $.ajax({ type: "POST", url: url, dataType: "text", error: function(){ online = false; $(document).trigger('status.networkDetection',[false]); }, success: function(){ online = true; $(document).trigger('status.networkDetection',[true]); } }); }; }; 

你可以在这里查看演示。 设置您的浏览器脱机工作,看看会发生什么…。 不,这不是很令人兴奋。

触发和绑定

令人兴奋的是(或者至less令我兴奋的是)通过应用程序传递状态的方法。 我偶然发现了一个基本上没有讨论过的使用jQuery触发器和绑定方法实现pub / sub系统的方法。

演示代码比需要的更钝。 networking检测对象将“状态”事件发布到主动监听它们的文档,并向所有用户发布“通知”事件(稍后的更多内容)。 这背后的原因是,在现实世界的应用程序中,可能会有更多的逻辑控制何时以及如何发布“通知”事件。

 $(document).bind("status.networkDetection", function(e, status){ // subscribers can be namespaced with multiple classes subscribers = $('.subscriber.networkDetection'); // publish notify.networkDetection even to subscribers subscribers.trigger("notify.networkDetection", [status]) /* other logic based on network connectivity could go here use google gears offline storage etc maybe trigger some other events */ }); 

由于jQuery的DOM中心方法事件发布到(触发)DOM元素。 这可以是一般事件的窗口或文档对象,也可以使用select器生成一个jQuery对象。 我演示的方法是创build一个命名空间的方法来定义用户。

作为用户的DOM元素简单归类为“用户”和“networking检测”。 然后,我们可以通过触发$(“.subscriber.networkDetection”)上的通知事件来仅将事件发布到这些元素(其中只有一个在演示中$(“.subscriber.networkDetection”)

作为#notifier.subscriber.networkDetection组的一部分的#notifier div具有绑定到它的匿名函数,有效地充当监听器。

 $('#notifier').bind("notify.networkDetection",function(e, online){ // the following simply demonstrates notifier = $(this); if(online){ if (!notifier.hasClass("online")){ $(this) .addClass("online") .removeClass("offline") .text("ONLINE"); } }else{ if (!notifier.hasClass("offline")){ $(this) .addClass("offline") .removeClass("online") .text("OFFLINE"); } }; }); 

所以,你去了。 这一切都相当冗长,我的例子并不令人兴奋。 它也没有展示你可以用这些方法做的任何有趣的事情,但是如果任何人都有兴趣从源头上挖掘自由。 所有的代码都内联在演示页面的头部

接受的答案中提供的链接显示了使用jQuery实现pub / sub系统的好方法,但是我发现代码有些难以阅读,所以这里是我简化版本的代码:

http://jsfiddle.net/tFw89/5/

 $(document).on('testEvent', function(e, eventInfo) { subscribers = $('.subscribers-testEvent'); subscribers.trigger('testEventHandler', [eventInfo]); }); $('#myButton').on('click', function() { $(document).trigger('testEvent', [1011]); }); $('#notifier1').on('testEventHandler', function(e, eventInfo) { alert('(notifier1)The value of eventInfo is: ' + eventInfo); }); $('#notifier2').on('testEventHandler', function(e, eventInfo) { alert('(notifier2)The value of eventInfo is: ' + eventInfo); }); 

我认为这样..有可能“绑定”自定义事件,如(来自: http : //docs.jquery.com/Events/bind#typedatafn ):

  $("p").bind("myCustomEvent", function(e, myName, myValue){ $(this).text(myName + ", hi there!"); $("span").stop().css("opacity", 1) .text("myName = " + myName) .fadeIn(30).fadeOut(1000); }); $("button").click(function () { $("p").trigger("myCustomEvent", [ "John" ]); }); 

我有一个类似的问题,但实际上是在寻找一个不同的答案。 我正在寻找创build一个自定义事件。 例如,而不是总是这样说:

 $('#myInput').keydown(function(ev) { if (ev.which == 13) { ev.preventDefault(); // Do some stuff that handles the enter key } }); 

我想把它缩写为:

 $('#myInput').enterKey(function() { // Do some stuff that handles the enter key }); 

触发器和绑定不告诉整个故事 – 这是一个JQuery插件。 http://docs.jquery.com/Plugins/Authoring

“enterKey”函数作为一个属性附加到jQuery.fn – 这是所需的代码:

 (function($){ $('body').on('keydown', 'input', function(ev) { if (ev.which == 13) { var enterEv = $.extend({}, ev, { type: 'enterKey' }); return $(ev.target).trigger(enterEv); } }); $.fn.enterKey = function(selector, data, fn) { return this.on('enterKey', selector, data, fn); }; })(jQuery); 

http://jsfiddle.net/b9chris/CkvuJ/4/

上面的一个好处是你可以处理键盘input优雅的链接监听器,如:

 $('a.button').on('click enterKey', function(ev) { ev.preventDefault(); ... }); 

编辑:已更新,正确地this上下文传递给处理程序,并将处理程序的任何返回值返回给jQuery(例如,如果您要取消事件和冒泡)。 更新为将适当的jQuery事件对象传递给处理程序,包括关键代码和取消事件的function。

老jsfiddle: http : //jsfiddle.net/b9chris/VwEb9/24/

这是一个旧的post,但我会尝试用新的信息更新它。

要使用自定义事件,您需要将其绑定到某个DOM元素并触发它。 所以你需要使用

.on()方法将事件types和事件处理函数作为参数。 可选地,它也可以接收事件相关数据作为其第二个参数,将事件处理函数推送到第三个参数。 任何传递的数据都可以用于事件对象的data属性中的事件处理函数。 事件处理函数总是接收事件对象作为其第一个参数。

.trigger()方法将事件types作为参数。 可选地,它也可以采用一组值。 这些值将作为事件对象之后的parameter passing给事件处理函数。

代码如下所示:

 $(document).on("getMsg", { msg: "Hello to everyone", time: new Date() }, function(e, param) { console.log( e.data.msg ); console.log( e.data.time ); console.log( param ); }); $( document ).trigger("getMsg", [ "Hello guys"] ); 

很好的解释可以在这里和这里find。 为什么这可能是有用的? 我发现如何在twitter工程师的这个优秀的解释中使用它。

PS在普通的JavaScript,你可以用新的CustomEvent做到这一点,但要小心IE和Safari的问题。

以下是我如何编写自定义事件:

 var event = jQuery.Event('customEventName); $(element).trigger(event); 

当然,你可以简单的做

 $(element).trigger('eventname'); 

但是我写的方式可以让你检测用户是否通过这样做防止了违约

 var prevented = event.isDefaultPrevented(); 

这允许您监听最终用户的请求,以停止处理特定事件,例如,如果单击表单中的button元素,但不希望表单发生错误。


我通常会这样听事件

 $(element).off('eventname.namespace').on('eventname.namespace', function () { ... }); 

再一次,你可以做

 $(element).on('eventname', function () { ... }); 

但是我一直觉得这个有点不安全,特别是如果你在一个团队工作的话。

以下没有错:

 $(element).on('eventname', function () {}); 

但是,假设我需要解除这个事件,无论出于什么原因(想象一个禁用的button)。 那我就不得不这样做了

 $(element).off('eventname', function () {}); 

这将从$(element)删除所有事件名称事件。 你不知道未来的某个人是否也会将某个事件绑定到这个元素上,而且你也会无意中将这个事件解除绑定

避免这种情况的安全方法是通过做命名空间事件

 $(element).on('eventname.namespace', function () {}); 

最后,你可能已经注意到,第一行是

 $(element).off('eventname.namespace').on('eventname.namespace', ...) 

个人总是在绑定一个事件之前解除绑定,以确保同一事件处理程序不会被多次调用(想象这是付款表单上的提交button,事件已被绑定5次)