使用FRP和Bacon.js优雅地处理双击和单击

时间:2013-07-30 05:13:49

标签: javascript functional-programming coffeescript frp bacon.js

我正试图找到最优雅的方式来区分Bacon.js中的单击和双击,但我觉得我并没有完全理解它是如何工作的。下面的工作用于检测双击,但我对于如何为单击事件优雅地指定不同的行为(即不同的回调函数)感到有点难过。

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

2 个答案:

答案 0 :(得分:4)

你可能最好单独使用“dblclick” - 你可以避免指定自己的定时间隔,只需点击一次即可。另一方面,通过直接使用“click”/“dblclick”,只要双击就会触发这两个事件。

如果您更喜欢指定自己的逻辑,那么它可能就像在长度上做不同的过滤器一样:

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

此外,通过使用flatmap创建单个点击流可能会使其更加优雅:

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

然后你可以进行onValue并比较值。

通过执行bufferWithTime(不计数),您还可以将三次单击分类为双击,但这取决于您所期望的行为。

答案 1 :(得分:2)

我对FRP来说很陌生,但做这样的事情会不会更好?

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') ...
});