jQuery中的自定义事件?

时间:2008-12-30 09:32:35

标签: jquery events

我正在寻找一些关于如何在jquery中以最佳方式实现自定义事件处理的输入。我知道如何连接dom元素中的事件,比如'click'等,但我正在构建一个小的javascript库/插件来处理一些预览功能。

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

那我该怎么做?我是否忽略了jquery中的一些内置功能来提升/处理用户事件,还是需要一些jquery插件才能做到这一点?您认为处理此问题的最佳方式/插件是什么?

6 个答案:

答案 0 :(得分:119)

接受的答案中提供的链接显示了使用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);
});

答案 1 :(得分:101)

看看这个:

(根据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的离线功能集成的jQuery UI,我一直在使用一些代码来使用jQuery轮询网络连接状态。

网络检测对象

基本前提很简单。我们创建一个网络检测对象的实例,它将定期轮询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]);
            }
        });
    };
};

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

触发并绑定

令人兴奋的是(或者至少令我兴奋的是)通过应用程序中继状态的方法。我偶然发现了一个使用jQuery的触发器和绑定方法实现pub / sub系统的未讨论的方法。

演示代码比它需要的更加迟钝。网络检测对象将“状态”事件发布到主动监听它们的文档,然后向所有订户发布“通知”事件(稍后将详细介绍)。这背后的原因是,在现实世界的应用程序中,可能会有更多的逻辑控制“通知”事件的发布时间和方式。

$(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元素。这可以是一般事件的窗口或文档对象,也可以使用选择器生成jQuery对象。我在演示中采用的方法是创建一种几乎命名空间的方法来定义订阅者。

将成为订阅者的DOM元素简单地归类为“subscriber”和“networkDetection”。然后,我们可以通过触发 $(“.subscriber.networkDetection”)

上的通知事件,仅将事件发布到这些元素(演示中只有一个元素)

#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");
        }
    };
});

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

答案 2 :(得分:20)

我想是这样的......可以“绑定”自定义事件,例如(来自: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" ]);
    });

答案 3 :(得分:14)

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

$('#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/

上述内容非常精确,您可以在链接侦听器上优雅地处理键盘输入,例如:

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

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

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

答案 4 :(得分:7)

这是一篇旧帖子,但我会尝试用新信息更新它。

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

  

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

  

.trigger()方法将事件类型作为其参数。可选地,它   也可以采用一系列值。这些值将传递给   事件处理函数作为事件对象之后的参数。

代码如下所示:

$(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"] );

可以找到好的解释herehere。为什么这有用呢?我在twitter engineer的这个出色的解释中找到了如何使用它。

P.S。在普通的javascript中,您可以使用new CustomEvent执行此操作,但请注意IE和Safari问题。

答案 5 :(得分:2)

以下是我创作自定义事件的方法:

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

当然,你可以做到

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

但是我编写的方式允许您通过执行

来检测用户是否已经阻止了默认值
var prevented = event.isDefaultPrevented();

这使您可以听取最终用户的请求以停止处理特定事件,例如,如果您单击表单中的按钮元素但不希望表单在发生错误时发布

然后我经常听这样的事件

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

再一次,你可以做到

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

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

以下内容没有错:

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

但是,假设我需要以任何理由解除绑定此事件(想象一下禁用按钮)。然后我必须做

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

这将从eventname中删除所有$(element)个事件。您无法知道将来某人是否也会将事件绑定到该元素,并且您无意中解除了该事件的绑定

避免这种情况的安全方法是通过执行

命名事件
$(element).on('eventname.namespace', function () {});

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

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

个人总是在绑定之前取消绑定事件,以确保永远不会多次调用相同的事件处理程序(想象这是付款表单上的提交按钮,并且事件已被绑定5次)