jQuery 中的自定义事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/399867/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Custom events in jQuery?
提问by Per Hornsh?j-Schierbeck
I'm looking for some input on how to implement custom eventhandling in jquery the best way. I know how to hook up events from the dom elements like 'click' etc, but I'm building a tiny javascript library/plugin to handle some preview functionality.
我正在寻找有关如何以最佳方式在 jquery 中实现自定义事件处理的一些输入。我知道如何从 dom 元素(如“click”等)中连接事件,但我正在构建一个小型 javascript 库/插件来处理一些预览功能。
I've got a script running to update some text in a dom element from a set of rules and data/user input I got, but now I need that same text shown in other elements that this script can't possibly know of. What I need is a good pattern to somehow observe this script producing the needed text.
我有一个脚本正在运行,以根据我获得的一组规则和数据/用户输入更新 dom 元素中的一些文本,但现在我需要在该脚本不可能知道的其他元素中显示相同的文本。我需要的是一个很好的模式来以某种方式观察这个脚本产生所需的文本。
So how do I do this? Did I overlook some builtin functionality in jquery to raise/handle user events or do I need some jquery plugin to do it? What do you think is the best way/plugin to handle this?
那么我该怎么做呢?我是否忽略了 jquery 中的一些内置功能来引发/处理用户事件,或者我是否需要一些 jquery 插件来做到这一点?您认为处理此问题的最佳方法/插件是什么?
采纳答案by Vitor Silva
Take a look at this:
看看这个:
(reprinted from the expired blog page http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/based on the archived version at http://web.archive.org/web/20130120010146/http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-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/)
Publish / Subscribe With jQuery
使用 jQuery 发布/订阅
June 17th, 2008
2008 年 6 月 17 日
With a view to writing a jQuery UI integrated with the offline functionality of Google Gears i've been toying with some code to poll for network connection status using jQuery.
为了编写与 Google Gears 的离线功能集成的 jQuery UI,我一直在尝试使用一些代码来使用 jQuery 轮询网络连接状态。
The Network Detection Object
网络检测对象
The basic premise is very simple. We create an instance of a network detection object which will poll a URL at regular intervals. Should these HTTP requests fail we can assume that network connectivity has been lost, or the server is simply unreachable at the current time.
基本前提非常简单。我们创建了一个网络检测对象的实例,它将定期轮询 URL。如果这些 HTTP 请求失败,我们可以假设网络连接已丢失,或者当前无法访问服务器。
$.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]);
}
});
};
};
You can view the demo here. Set your browser to work offline and see what happens…. no, it's not very exciting.
您可以在此处查看演示。将浏览器设置为离线工作,看看会发生什么...... 不,这不是很令人兴奋。
Trigger and Bind
触发和绑定
What is exciting though (or at least what is exciting me) is the method by which the status gets relayed through the application. I've stumbled upon a largely un-discussed method of implementing a pub/sub system using jQuery's trigger and bind methods.
令人兴奋的(或者至少是让我兴奋的)是通过应用程序传递状态的方法。我偶然发现了一种使用 jQuery 的触发器和绑定方法实现发布/订阅系统的主要未讨论的方法。
The demo code is more obtuse than it need to be. The network detection object publishes 'status ‘events to the document which actively listens for them and in turn publishes ‘notify' events to all subscribers (more on those later). The reasoning behind this is that in a real world application there would probably be some more logic controlling when and how the ‘notify' events are published.
演示代码比它需要的更钝。网络检测对象将“状态”事件发布到主动侦听它们的文档,然后将“通知”事件发布给所有订阅者(稍后会详细介绍)。这背后的原因是,在现实世界的应用程序中,可能会有更多的逻辑控制何时以及如何发布“通知”事件。
$(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
*/
});
Because of jQuery's DOM centric approach events are published to (triggered on) DOM elements. This can be the window or document object for general events or you can generate a jQuery object using a selector. The approach i've taken with the demo is to create an almost namespaced approach to defining subscribers.
由于 jQuery 的以 DOM 为中心的方法,事件被发布到(触发)DOM 元素。这可以是一般事件的窗口或文档对象,也可以使用选择器生成 jQuery 对象。我在演示中采用的方法是创建一个几乎命名空间的方法来定义订阅者。
DOM elements which are to be subscribers are classed simply with “subscriber” and “networkDetection”. We can then publish events only to these elements (of which there is only one in the demo) by triggering a notify event on $(“.subscriber.networkDetection”)
要成为订阅者的 DOM 元素被简单地分类为“订阅者”和“网络检测”。然后我们可以通过触发一个通知事件来仅将事件发布到这些元素(演示中只有一个)$(“.subscriber.networkDetection”)
The #notifier
div which is part of the .subscriber.networkDetection
group of subscribers then has an anonymous function bound to it, effectively acting as a listener.
作为订阅者组#notifier
一部分的div.subscriber.networkDetection
然后绑定了一个匿名函数,有效地充当侦听器。
$('#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");
}
};
});
So, there you go. It's all pretty verbose and my example isn't at all exciting. It also doesn't showcase anything interesting you could do with these methods, but if anyone's at all interested to dig through the source feel free. All the code is inline in the head of the demo page
所以,你去了。这一切都非常冗长,我的例子一点也不令人兴奋。它也没有展示你可以用这些方法做的任何有趣的事情,但如果有人有兴趣挖掘源代码,请随意。所有代码都内联在演示页面的头部
回答by Manuel Navarro
The link provided in the accepted answer shows a nice way to implement the pub/sub systemusing jQuery, but I found the code somewhat difficult to read, so here is my simplified version of the code:
接受的答案中提供的链接显示了使用 jQuery实现发布/订阅系统的好方法,但我发现代码有些难以阅读,因此这是我的代码的简化版本:
$(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);
});
回答by Tuxified
I think so.. it's possible to 'bind' custom events, like(from: http://docs.jquery.com/Events/bind#typedatafn):
我认为是这样......可以“绑定”自定义事件,例如(来自: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" ]);
});
回答by Chris Moschini
I had a similar question, but was actually looking for a different answer; I'm looking to create a custom event. For example instead of always saying this:
我有一个类似的问题,但实际上是在寻找不同的答案;我正在寻找创建一个自定义事件。例如,而不是总是这样说:
$('#myInput').keydown(function(ev) {
if (ev.which == 13) {
ev.preventDefault();
// Do some stuff that handles the enter key
}
});
I want to abbreviate it to this:
我想将其缩写为:
$('#myInput').enterKey(function() {
// Do some stuff that handles the enter key
});
trigger and bind don't tell the whole story - this is a JQuery plugin. http://docs.jquery.com/Plugins/Authoring
trigger 和 bind 并不能说明整个故事 - 这是一个 JQuery 插件。 http://docs.jquery.com/Plugins/Authoring
The "enterKey" function gets attached as a property to jQuery.fn - this is the code required:
“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/
http://jsfiddle.net/b9chris/CkvuJ/4/
A nicety of the above is you can handle keyboard input gracefully on link listeners like:
上面的一个优点是您可以在链接侦听器上优雅地处理键盘输入,例如:
$('a.button').on('click enterKey', function(ev) {
ev.preventDefault();
...
});
Edits: Updated to properly pass the right this
context to the handler, and to return any return value back from the handler to jQuery (for example in case you were looking to cancel the event and bubbling). Updated to pass a proper jQuery event object to handlers, including key code and ability to cancel event.
编辑:更新以正确地将正确的this
上下文传递给处理程序,并将任何返回值从处理程序返回给 jQuery(例如,如果您希望取消事件和冒泡)。更新以将适当的 jQuery 事件对象传递给处理程序,包括关键代码和取消事件的能力。
Old jsfiddle: http://jsfiddle.net/b9chris/VwEb9/24/
旧 jsfiddle:http: //jsfiddle.net/b9chris/VwEb9/24/
回答by Salvador Dali
It is an old post, but I will try to update it with a new information.
这是一个旧帖子,但我会尝试用新信息更新它。
To use custom events you need to bind it to some DOM element and to trigger it. So you need to use
要使用自定义事件,您需要将其绑定到某个 DOM 元素并触发它。所以你需要使用
.on() method takes an event type and an event handling function as arguments. Optionally, it can also receive event-related data as its second argument, pushing the event handling function to the third argument. Any data that is passed will be available to the event handling function in the data property of the event object. The event handling function always receives the event object as its first argument.
.on() 方法将事件类型和事件处理函数作为参数。可选地,它还可以接收与事件相关的数据作为其第二个参数,将事件处理函数推送到第三个参数。传递的任何数据都可用于事件对象的数据属性中的事件处理函数。事件处理函数总是接收事件对象作为它的第一个参数。
and
和
.trigger() method takes an event type as its argument. Optionally, it can also take an array of values. These values will be passed to the event handling function as arguments after the event object.
.trigger() 方法将事件类型作为其参数。或者,它也可以采用一组值。这些值将在事件对象之后作为参数传递给事件处理函数。
The code looks like this:
代码如下所示:
$(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"] );
Nice explanation can be found hereand here. Why exactly this can be useful? I found how to use it in this excellent explanation from twitter engineer.
可以在这里和这里找到很好的解释。为什么这会很有用?我在twitter 工程师的这篇精彩解释中找到了如何使用它。
P.S.In plain javascript you can do this with new CustomEvent, but beware of IE and Safari problems.
PS在普通的 javascript 中,您可以使用new CustomEvent执行此操作,但要注意 IE 和 Safari 问题。
回答by Luke Madhanga
Here is how I author custom events:
以下是我编写自定义事件的方式:
var event = jQuery.Event('customEventName');
$(element).trigger(event);
Granted, you could simply do
当然,你可以简单地做
$(element).trigger('eventname');
But the way I wrote allows you to detect whether the user has prevented default or not by doing
但是我写的方式允许您通过执行以下操作来检测用户是否阻止了默认值
var prevented = event.isDefaultPrevented();
This allows you to listen to your end-user's request to stop processing a particular event, such as if you click a button element in a form but do not want to the form to post if there is an error.
这允许您听取最终用户停止处理特定事件的请求,例如,如果您单击表单中的按钮元素但不希望表单在出现错误时发布。
I then usually listen to events like so
然后我通常会听这样的事件
$(element).off('eventname.namespace').on('eventname.namespace', function () {
...
});
Once again, you could just do
再一次,你可以做
$(element).on('eventname', function () {
...
});
But I've always found this somewhat unsafe, especially if you're working in a team.
但我一直觉得这有点不安全,特别是如果你在一个团队中工作。
There is nothing wrong with the following:
以下没有任何问题:
$(element).on('eventname', function () {});
However, assume that I need to unbind this event for whatever reason (imagine a disabled button). I would then have to do
但是,假设我需要因任何原因解除绑定此事件(想象一个禁用的按钮)。我将不得不做
$(element).off('eventname', function () {});
This will remove all eventname
events from $(element)
. You cannot know whether someone in the future will also bind an event to that element, and you'd be inadvertently unbinding that event as well
这将从中删除所有eventname
事件$(element)
。您无法知道将来是否有人也会将事件绑定到该元素,并且您也会无意中解除绑定该事件
The safe way to avoid this is to namespace your events by doing
避免这种情况的安全方法是通过执行以下操作来命名您的事件
$(element).on('eventname.namespace', function () {});
Lastly, you may have noticed that the first line was
最后,您可能已经注意到第一行是
$(element).off('eventname.namespace').on('eventname.namespace', ...)
I personallyalways unbind an event before binding it just to make sure that the same event handler never gets called multiple times (imagine this was the submit button on a payment form and the event had been bound 5 times)
我个人总是在绑定一个事件之前解除绑定它只是为了确保同一个事件处理程序永远不会被多次调用(想象一下这是付款表单上的提交按钮并且该事件已被绑定 5 次)