2

I'm trying to find the most graceful way to distinguish between single and double clicks in Bacon.js, but I feel like I'm not completely grasping how this works. The following works for detecting a double-click, but I'm a bit stumped as to how I would specify different behavior (i.e., a different callback function) elegantly for a single-click event.

  clicked = Bacon.fromEventTarget(document, "click")
  clicked.bufferWithTimeOrCount(300, 2)
          .filter((x) -> x.length is 2)
          .onValue (x) ->
            console.log "double clicked: ", x
Brendan
  • 511
  • 1
  • 3
  • 11

2 Answers2

4

You would probably be better off using "dblclick" for that separately - you will avoid the need to specify your own timing interval for what counts as a single-click vs. a double-click. On the other hand, with the straightforward use of "click"/"dblclick" both events will be fired in case of a double-click.

If you prefer specifying your own logic, then it would probably be as doing a different filter on the length:

clicked = Bacon.fromEventTarget(document, "click")
buffered = clicked.bufferWithTimeOrCount(300, 2)
buffered.filter((x) -> x.length is 2)
        .onValue (x) ->
          console.log "double clicked: ", x            
buffered.filter((x) -> x.length is 1)
        .onValue (x) ->
          console.log "single clicked: ", x

Also, perhaps it could be made more elegant by using flatmap to create a single stream of clicks:

clicks = clicked.bufferWithTime(300)
   .flatMap((x) ->
     if (x.length < 2) 
       Bacon.once("single")
     else 
       Bacon.once("double")
   )

Then you can do your onValue and compare the values.

By doing bufferWithTime (without count) you will classify a triple-click as a double-click as well, but it depends on what your desired behaviour is.

AndriusA
  • 66
  • 4
  • 1
    I don't see why use flatMap when you could use map. In this case you are always returning a stream of a single event, so there's no need for the extra power provided by flatMap. – raimohanska Aug 15 '13 at 19:43
2

I am pretty much new to FRP, however wouldn't be better to do something like this?

var clicks = Bacon.fromEventTarget(document, 'click').merge(
    Bacon.fromEventTarget(document, 'dblclick')
);

clicks.onValue(event, function(ev) {
    if (ev.type === 'click') ...
    else if (ev.type === 'dblclick') ...
});
FredyC
  • 3,999
  • 4
  • 30
  • 38