

Google open-sources JsAction, a JavaScript event delegation library - ruidlopes
https://github.com/google/jsaction

======
scotty79
So this (with specialized lib, and fairly large unintuitive js code to set
whole thing up):

    
    
            <div id="foo" jsaction="leftNav.clickAction;
                 dblclick:leftNav.doubleClickAction">
    

is pretty much the same as this:

    
    
            <div id="foo"
                 onclick="Actions.leftNav.clickAction()" 
                 ondblclick="Actions.leftNav.doubleClickAction()">
    

without any abusing or manipulating of html and dom and with setup as simple
and understandable as this:

    
    
            window.Actions = {
                leftNav: {
                    clickAction: function() {
                        myApp.LeftNav.doSomeSeriousStuff();
                    },
                    doubleClickAction: function() {
                        // very late loading of implementation
                        require("LeftNavActions", function(LeftNavActions) { 
                            LeftNavActions.doSomeOtherSeriousStuff();
                        })
                    },
                    // if you want add handlers from other places 
                    // with Actions.leftNav._anotherAction.push()
                    _anotherAction: [],
                    anotherAction: function() {
                        this._anotherAction.forEach(function(a) { a(); });
                    }
    
                }
            }
    
    
    

Actions is a good idea that I remember from Delphi 4. It is just one
additional layer of indirection that enables you to attach same behavior for
example to menu option and toolbar button.

~~~
marcus_holmes
I like the syntax, but it bugs me that the behaviour goes into the HTML. I
really like keeping my event mapping in the javascript so I keep a clean
separation between structure in the HTML and behaviour in the JS.

~~~
Kiro
I don't know. I think the one of the best things about Angular for example is
that you often see straight away what's happening because of it's declarative
nature. With normal event handlers you don't know what's going on until you
specifically search for the id/class/tag in all the JS files.

~~~
egeozcan
In that case, it's good to have some conventions but I agree that it takes a
very small amount of carelessness for maintenance to become a PITA. I think
using reactive templates which associate with a model is better than declaring
every reaction on the DOM level though.

------
floatrock
The API could use some work. To implement the simplest example, I need to
remember patterns like:

> eventContract.dispatchTo(goog.bind(dispatcher.dispatch, dispatcher));

imho, there's a problem if you need to dust off your gang of four book to
understand the API. Might as well include an
AbstractSingletonProxyFactoryBean.

~~~
couchand
The API could certainly use some work, and it's worse than you mention. If it
were just a matter of applying widely-known Gang of Four patterns it would be
fine. All over the place it looks like the designer didn't realize there's a
built-in Function.prototype.bind.

~~~
gefh
In IE8 and FF3.6, there isn't. If you believe netmarketshare.com, that's 20%
of users right there.

~~~
superlupo
If you are not relying on edge case behaviour of Function.prototype.bind,
including the polyfill here should be enough:
[https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Compatibility)

------
rabino
I like they are putting this on Github instead of (or on top of) Google Code

~~~
camus2
Google code could have been great.But the UX sucks so much and has never been
updated.

Github is successfull because of git AND its good clean UX.

Google code feels like developpers were in charge of the UX. It's a UX
disaster and will be retired sooner or later.

~~~
Cthulhu_
it's a shame TBH, Google Code could have a lot of potential, if only because
Google as a company is chock full of developers. Maybe not as much UX
designers though.

------
riskable
This seems pretty complicated and not so simple. Someone else asked, "How is
this better than Backbone?" Backbone is (a lot) more than just an event lib. A
better question would be, "How is this better than OnOff?" (which is basically
the equivalent of the events part of Backbone):

[https://github.com/LiftoffSoftware/OnOff](https://github.com/LiftoffSoftware/OnOff)

~~~
modarts
How is OnOff better than just the standard EventEmitter?

~~~
riskable
You mean Node.js's EventEmitter? That's not built into JavaScript (i.e. not a
"standard").

Anyway, OnOff is better because:

1\. It's smaller. 2\. It's simpler/less complicated.

Also, it doesn't need a noConflict option due to the way it gets instantiated.

------
distracteddev90
Is it just me or is this overly complex for what amounts to declaring an
EventEmitter, requiring it where needed, and proxying dom events to that
EventEmitter?

------
scotty79
Yes. Let's reinvent onclick attribute. What's with the recent trend of putting
logic and visual configuration back into xmllish html clutter where you can't
see it among the </>=" and meaningless words like div, span, class? Did people
forget how much of a good idea was binding stuff to html from far away, from
js and css files?

Did new programmers evolved some new protein that prevents their eyes from
bleeding when they try to find bits of actual meaning in xml files?

~~~
colbyh
Having actions tied to the object declaratively is a paradigm that javascript
frameworks have been moving towards, rather than away from, for the past few
years.

When managing a complex, JS-heavy application, it is infinitely more developer
friendly to be able to look at an element and figure out what the lifecycle of
that object might look like. Instead of digging through javascript (especially
jquery heavy code with the possibility of obscured references) where there's
no real logic behind when or where an object might be modified, you restrict
it to the most basic element possible - the HTML declaration.

So yes, let's please reinvent HTML :-)

~~~
scotty79
> When managing a complex, JS-heavy application, it is infinitely more
> developer friendly to be able to look at an element and figure out what the
> lifecycle of that object might look like.

Except that what you see in your html is not your element. It's just a forced
structure required by w3c (described with xml syntax) for some aspects of
visual representation of your element.

Your element should be described in js where it can be fairly easily separated
out to a single file, and where binding configuration (as well as other
concerns such as communication with backend or other app components for
example) might be in one place instead of being interspersed with html tags
unrelated to that behavior. See how backbone does event binding in views to
understand what I'm talking about.

> So yes, let's please reinvent HTML

HTML is not so much an invention as result of glacial (or w3c-ish in other
words) process of semi-(mis)directed evolution.

I'm guessing you never had to implement a layout using tables and 1px
transparent gifs. I encourage you to try. It might make you understand how
rigid and misaligned with the goal HTML in its spirit is. It got some
improvements over the years but there was nothing revolutionary in its
development even for fairly mild definitions of "revolutionary". Flexbox might
become one such mini-revolution when few generations of IE do world a favor
and die already.

JavaScript is far from being perfect and you can make a horrible mess of it as
well, but at least it's general purpose language that supports various
mechanisms for abstracting and organizing things and fairly minimalist syntax
(as compared to xml, html) for declaring/organizing things that got wide
appreciation as JSON.

~~~
colbyh
Javascript, in a browser, exists to manipulate the document. If your opinion
is that decoupling the elements of that document from the actions that might
happen as a result of interacting with that element then so be it, but I
couldn't disagree more. Even if it allows them to live in a "nicer" language
(JS vs HTML), I'd rather everything be declared up front.

Reading someone else's Backbone code (as compared to Angular or Ember) is
really, really not fun for me. YMMV though. Luckily for me, most modern JS
frameworks are similarly opinionated.

~~~
scotty79
> I'd rather everything be declared up front.

I'm all for declaring up front, just not in html.

> Reading someone else's Backbone code (as compared to Angular or Ember) is
> really, really not fun for me.

Backbone is far from what I consider good readability. If encourages bad
habits by not providing templating and sort of encouraging use of jQuery for
dom modification. Binding events to backbone view is what I consider good
readability.

~~~
colbyh
Finally, we can both agree that jquery dom manipulation is a great way to find
yourself in a mess of unmaintainable code.

If you're a fan of backbone views though - why not React? IMO it's very
similar to backbone but with sane structure and an incredibly powerful render
loop.

~~~
scotty79
I haven't paid much attention to React before reading this
[http://jlongster.com/Removing-User-Interface-
Complexity,-or-...](http://jlongster.com/Removing-User-Interface-
Complexity,-or-Why-React-is-Awesome)

Now I think the idea is awesome and architecture that arises from it might be
very good. But this idea assumes that DOM manipulation is fast enough to do
every render frame and I do not trust yet the caching magic that React.js
conjures to ameliorate the fact that it actually isn't.

------
wldlyinaccurate
Is it just me, or does this not seem "tiny" at all? It seems to require a
bunch of Closure modules, and on top of that the source itself is hundreds of
lines (albeit with comments).

Nitpicking aside, it looks like an interesting approach to decoupling the DOM
from your event handlers. Personally I'm happy sticking with the standard
on{event} attributes for really simple stuff.

~~~
espeed
The Closure advanced compiler can reduce the size significantly
([https://developers.google.com/closure/compiler/docs/compilat...](https://developers.google.com/closure/compiler/docs/compilation_levels)).

------
Raynos
This seems similar to a module I wrote called [html-delegator][1].

The separation of thing that emits named event and listener is a good idea.

I Actually moved away from the HTML attribute DSL and started putting named
events in my virtual dom instead (using [mercury][2])

The important part of this approach that is not shown in js action is to
ensure you emit data structures instead of dom event objects to the listeners.

    
    
      [1]: https://github.com/Raynos/html-delegator/blob/master/README.md
      [2]: https://github.com/Raynos/mercury

------
jgmmo
How does this compare with RX.js where they use the Observable setup to work
with collections of events? Like that Netflix talk that was up here last week?

------
underwater
This looks very similar to the concept of "sigils" in Javelin:
[https://secure.phabricator.com/book/javelin/article/sigils_m...](https://secure.phabricator.com/book/javelin/article/sigils_metadata/)

------
mmastrac
Interesting. This might have come from the Google+ development team, as this
and something called "jsmodel" are part of that product. You can see traces of
both of these in the DOM of plus.google.com

~~~
cramforce
Actually you can also see traces of the jsaction attribute in the G+ product.
G+ isn't using this from the group up though. It has a pretty long history at
Google, so I'm not even sure where it came from. Should have been either Maps
or Search.

~~~
zaphar
It started in maps. At the time IE had some issues with memory leaks when dom
elements with an event listener attached were deleted. This allowed them to
have just one listener for the page.

------
dudus
Seems like this has to be "compiled" with clojure compiler. I'm not very
familiar with this. Can someone provide some rough instructions to actually
get the "compiled" library?

~~~
espeed
The Google _Closure_ compiler [1] (not Clojure); however, this is easy to mix
up since ClojureScript [2] is built on Google Closure and uses the Google
Closure compiler.

[1]
[https://developers.google.com/closure/compiler/docs/compilat...](https://developers.google.com/closure/compiler/docs/compilation_levels)

[2]
[https://github.com/clojure/clojurescript](https://github.com/clojure/clojurescript)

------
mkaziz
Why is this better than something like backbone, for instance?

~~~
michaelmior
JsAction provides a subset of the functionality provided by Backbone. In terms
of how the two handle event delegation, in JsAction, the events are defined in
the DOM. With Backbone, you typically define the events in the view which
should process them. It's open for debate which is better.

~~~
scotty79
> It's open for debate which is better.

Which is same debate as between onclick and addEventListener only with
slightly less verbose syntax on both sides of the debate and some implicit
scoping that makes it possible.

~~~
cramforce
Not a zero sum game though (although I do realize this is hackernews :).
addEventListener is sometimes strictly better than using jsaction. i.e. it
supports removing event listeners. That is fine. Right tool for the job.

onclick-like functionality is coming back to frameworks. Angular and Polymer
both have variations of what jsaction provides as a single-purpose library. It
is sometimes just much nicer to bind stuff together directly.

~~~
scotty79
> onclick-like functionality is coming back to frameworks. Yes. I've noticed
> and as you might have guessed I'm equally deeply astonished and saddened.

> It is sometimes just much nicer to bind stuff together directly. Yes. It's
> so much nicer to have your hammer at your desk than to go to a cabinet to
> fetch it when you need it. But if you own bunch of tools and do various task
> at your desk it's either cabinet or a pile on you desk that at some point
> prevents you from making any progress on your projects.

Things should be kept separated out and organised by concern. If they are
brought together it is either for convenience or speed. Both perfectly valid
reasons so the separation is never strict but should be viewed as exception
not as a rule. If you don't watch yourself you might end up with oscommerce
PHP source files where everything is together because it's so much nicer to
bind stuff directly.

