Skip to content

Instantly share code, notes, and snippets.

@cowboy
Last active June 8, 2023 02:22
Star You must be signed in to star a gist
Embed
What would you like to do?
jQuery Tiny Pub/Sub: A really, really, REALLY tiny pub/sub implementation for jQuery.
/* jQuery Tiny Pub/Sub - v0.7 - 10/27/2011
* http://benalman.com/
* Copyright (c) 2011 "Cowboy" Ben Alman; Licensed MIT, GPL */
(function($) {
var o = $({});
$.subscribe = function() {
o.on.apply(o, arguments);
};
$.unsubscribe = function() {
o.off.apply(o, arguments);
};
$.publish = function() {
o.trigger.apply(o, arguments);
};
}(jQuery));
/* jQuery Tiny Pub/Sub - v0.7 - 10/27/2011
* http://benalman.com/
* Copyright (c) 2011 "Cowboy" Ben Alman; Licensed MIT, GPL */
(function(a){var b=a({});a.subscribe=function(){b.on.apply(b,arguments)},a.unsubscribe=function(){b.off.apply(b,arguments)},a.publish=function(){b.trigger.apply(b,arguments)}})(jQuery)
@javascripter
Copy link

Zepto only makes use of the DOM-based event system so there's no way to get a real empty element to work as the global pub/sub object. We might as well use ("").

@kodi
Copy link

kodi commented Oct 12, 2012

I wrapped this into AMD module to use it with require.js

define(function () {

    "use strict";

    /**
     *    Events. Pub/Sub system for Loosely Coupled logic.
     *    Based on Peter Higgins' port from Dojo to jQuery
     *    https://github.com/phiggins42/bloody-jquery-plugins/blob/master/pubsub.js
     *
     *    Re-adapted to vanilla Javascript
     *
     *    ----------------------------------------------------------
     *    And then wrapped to AMD Module by Dragan Bajcic @kodisha
     *
     *    @class Events
     */
    return {
        cache : {},
        /**
         *    Events.publish
         *    e.g.: Events.publish("/Article/added", [article], this);
         *
         *    @class Events
         *    @method publish
         *    @param topic {String}
         *    @param args    {Array}
         *    @param scope {Object=} Optional
         */
        publish : function (topic, args, /** {Object=} */ scope) {

            console.log('publish',topic, args);
            if (this.cache[topic]) {
                var thisTopic = this.cache[topic],
                    i = thisTopic.length - 1;

                for (i ; i >= 0 ; i -= 1) {
                    thisTopic[i].apply(scope || this, args || []);
                }
            }
        },
        /**
         *    Events.subscribe
         *    e.g.: Events.subscribe("/Article/added", Articles.validate)
         *
         *    @class Events
         *    @method subscribe
         *    @param topic {String}
         *    @param callback {Function}
         *    @return Event handler {Array}
         */
        subscribe : function (topic, callback) {

            console.log('subscribe', topic, callback);
            if (!this.cache[topic]) {
                this.cache[topic] = [];
            }
            this.cache[topic].push(callback);
            return [topic, callback];
        },
        /**
         *    Events.unsubscribe
         *    e.g.: var handle = Events.subscribe("/Article/added", Articles.validate);
         *        Events.unsubscribe(handle);
         *
         *    @class Events
         *    @method unsubscribe
         *    @param handle {Array}
         *    @param completly {Boolean}
         *    @return {type description }
         */
        unsubscribe : function (handle, completly) {
            var t = handle[0],
                i = this.cache[t].length - 1;

            if (this.cache[t]) {
                for (i ; i >= 0 ; i -= 1) {
                    if (this.cache[t][i] === handle[1]) {
                        this.cache[t].splice(this.cache[t][i], 1);
                        if (completly) {
                            delete this.cache[t];
                        }
                    }
                }
            }
        }
    };

});

@stsvilik
Copy link

I have only one concern/suggestion to this relatively simple PubSub - it doesn't take into account published events that have already happened (in the past). Why is this important? Assume for a second that I want to subscribe to an event that had already happened, or I dont know that it happened, but still want my new subscriber to be triggered with the last-published values? My suggestion is to add something like this:

(function($) {

var o = $({}), pastEvents = {};

$.subscribe = function() {
var type = arguments.slice(0, 1)[0],
handler = arguments.slice(-1)[0];
//Fire your subscribe handler if event has already happened
if(type in pastEvents) {
pastEvents[type].done(function() {
handler.apply(o, arguments);
});
}
//Subscribe to future events as well
o.on.apply(o, arguments);
};

$.unsubscribe = function() {
o.off.apply(o, arguments);
};

$.publish = function() {
var type = arguments.slice(0, 1)[0],
data = arguments.slice(1)[0];
//Preserve data for future subscribers to this event
pastEvents[type] = $.Deferred().resolve(data).promise();
o.trigger.apply(o, arguments);
};

}(jQuery));

@chrisclarke1977
Copy link

Even smaller just for sillyness

var o=$({}),s='subscribe';
$.each({on:s,off:'un'+s,trigger:'publish'},function(k,v){$[v]=function(){o[k].apply(o,arguments)};});

@zaus
Copy link

zaus commented Feb 11, 2013

If we're talking about relative sizes, why use "publish/subscribe" nomenclature? Just stick with "on/off/trigger" (or my preferred "on/off/do").

UPDATE I just found out why the "pros" stick to trigger instead of do (boo <IE9).

Example: https://gist.github.com/zaus/4756518

/* jQuery Tinier Pub/Sub - v0.9b - "on/off/do version" - 2013-02-11
 * original by http://benalman.com/ 10/27/2011
 * Original Copyright (c) 2011 "Cowboy" Ben Alman; Licensed MIT, GPL */

(function($) {

  // "topic" holder
  var o = $({});

  // attach each alias method
  $.each({on:0,off:0,"go":'trigger'}, function(alias,method) {
    $[alias] = function(topic, callbackOrArgs) {
        o[method || alias].apply(o, arguments);
    }
  });

}(jQuery));

@zaus
Copy link

zaus commented Feb 19, 2013

@connected - what's the default event you're trying to prevent? isn't this limited to the arbitrary hidden topic var o? just curious.

@aghouseh
Copy link

@kodi thanks for the requirejs module implementation!

@mediafreakch
Copy link

How would you add support for wildcards in the topic name? Does it even make sense as jQuery doesn't support wildcards for event names? Or is using a standalone pub/sub library the better approach?

@gmanish
Copy link

gmanish commented Dec 4, 2015

I know some javascript and little of jQuery (been playing with Ember, just for fun). I understand the on off methods, but I do not understand what var o = $({}); does. Can anyone please explain?

As always, google doesn't consider these braces and the $ in its search results.

@shshaw
Copy link

shshaw commented Apr 14, 2016

@gmanish var o = $({}) simply creates a jQuery collection with an empty object {} that becomes the recipient of all the event triggers. As other comments show, the recipient could be anything like $('<b />').

@Kiodaddy
Copy link

I am telling you this is working really good.

@ahmed-musallam
Copy link

@lanikane
Copy link

Your article is very helpful for me. I am very impressed with your article. It gives me a lot of interesting information about quordle moviedle . Thank you very much.

@Rosendamans
Copy link

I suppose I should pose that issue on a Zepto forum, but I thought someone might have a workaround here. awnings near me Toms River NJ

@joanadavidson
Copy link

Zepto only makes use of the DOM-based event system so there's no way to get a real empty element to work as the global pub/sub-object. We might as well use ("").

Joana | peeling wallpaper

@biano22
Copy link

biano22 commented Sep 29, 2022

Thank you very much for your sharing, it has helped me in my great work, I have reduced my working time a lot because of you. I have coded some games like quordle , temple run .. if you are interested please connect with me.

@andrewmcmason
Copy link

Very elegant and clean code! Good job Ben! I've been using it personally at both my fun projects over at Taylordle and also Quordle game

@andrewmcmason
Copy link

I strongly believe that react is the way to go, especially when you are planning on having 1M+ visitors per day. A clear example is Wordle.gg which is a wordle game site and they are built using React

@AmoeScott
Copy link

I will try that code. Thank you. https://cincinnati-seo.com/

@andrewmcmason
Copy link

Can someone help please with a TypeScript version? I'm trying to implement it on nyt crossword answers

@leeannpor89
Copy link

The coding was complicated but thank you for sharing it with us. I would even share this with my friend working at Snow Removal Kamloops.

@joanadavidson
Copy link

I still receive notifications about this thread even when i'm in El Paso. Any update?

@SEO11SEO
Copy link

code is perfect i hope to see more kleinanzeigen

@michsullivan015
Copy link

I had a difficult time understanding the code. I'm having an headache. If interested, please visit our website.

@montans
Copy link

montans commented Mar 15, 2023

It allows different aspects of your application, usually called modules, to both subscribe to events other modules might publish, & publish ...
balenaetcher website & krnl download.

@parasthackral
Copy link

In just three easy steps, Balena Etcher promises to burn operating system images to SD cards and portable ffh4x apk media flawlessly.

@parasthackral
Copy link

The Aurora store was initially based on Sergei Yeriomin's Yalp store, but v3.0 krnl apk has been completely rewritten to run on all Android 5.0 devices following Material Design Rewritten.

@parasthackral
Copy link

A free Android app called PGSharp apk and aniyomi apk lets you change where your Pokémon GO GPS is. This software lets you control how your Avatar moves without actually moving.

@rickluck90
Copy link

Cool! I'll surely be coming back for the next posts from you. Rick from Residential Painters in Regina

@gringoxpcom
Copy link

Thanks for sharing this amazing post synapse x website and also btroblox website.

@ionutzp
Copy link

ionutzp commented Apr 1, 2023

@cowboy this gist is getting spammed

@fps-unlockers
Copy link

You can Update The script Or Using Script KRNL for CHeat In Roblox
We Updated Our script on Regular Basisco

@chavesarlene4
Copy link

chavesarlene4 commented Apr 21, 2023

Thanks for sharing this fantastic content. You have really inspired me to blog. however, you can do a check. snow-removal-grande-prairie

@gekksolol
Copy link

Rice Purity Test is a 100-question survey that assesses the participants’ supposed degree of innocence in worldly matters.

@gekksolol
Copy link

Instander APK Download is a highly sought-after variant of Instagram, but it is not readily available on the Google Play store. To gain access to its additional features, you will need to download this modded version. In this post, I'll outline the steps to download and install Instander APK so that you can make the most out of your Instagram experience. Fortunately, this exceptional app can be downloaded from this website completely free of charge.

@gekksolol
Copy link

LibreTube Mod APK is an application for you to watch movies and much other interesting content anonymously and privately.

@philipwhitehead
Copy link

philipwhitehead commented May 3, 2023

how to apply smooth handling effects in website using jquery or javascript.
https://southamptonfencingpros.com/

@lindausa0106
Copy link

Thank you for the information you share, I will read it carefully and check if there are any mistakes, and I will respond. mapquest directions

@bellidzx
Copy link

Thanks a lot for this wonderful info. It helped me a lot! Custom Metal Design

@paulmorgan793
Copy link

paulmorgan793 commented May 25, 2023

I have heard that JQuery is so easy to implement as compared to JS.
https://harrogatetreesurgeons.co.uk/

@MolinaKim
Copy link

This is amazing. Cheers from our https://bankownedlifeinsurance.org/

@MolinaKim
Copy link

Thank you for sharing. I am loving this. For affordable insurance, come visit us at https://redbirdagents.com/

@chahatmittal
Copy link

Thank you for sharing. It's amazing and if you want to listen ad free music on spotify then check this xManager app

@pcarroll920
Copy link

I really liked the website you have. I will visit him regularly. I'd like to chat with you. I appreciate that you please respond to the e-mail that you will see in this comment.
Party Bus New Brunswick

@elitepipeiraq
Copy link

Thank you for sharing. It's amazing and if you want to check some hdpe itmes plastic factory

@MolinaKim
Copy link

Always love reading this. Cheers from https://www.eaglenola.com/

@sohailshoaibee
Copy link

MODFunda is the ultimate destination for modded APK enthusiasts! Your website has made it incredibly easy for me to find and download modded versions of my favorite apps. I appreciate the detailed descriptions and instructions accompanying each mod. Thank you for creating such a valuable resource!

@sohailshoaibee
Copy link

I recently stumbled upon Hydrogen Executor https://hydrogenexecutor.vip/, and I must say, it's a treasure trove of information about Hydrogen Executor! The website provides a wealth of knowledge and insights for beginners and experts alike. The easy-to-navigate interface and well-organized content make learning about Hydrogen Executor a breeze. Great job, Hydrogen Executor!

@jessicavi7395
Copy link

This is a great piece that teaches and comes up with new ideas for retro games.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment