4

I need to implement a behavior:

  • when element clicked - one thing happens
  • but when it's clicked and held for more than one second, something else happens (e.g element becomes draggable) and then the first event never fires

I think I know how to catch click&hold type of events, but how to distinguish between first and second?

Can you show me how to do that using this jsbin. I already made the "click, hold & drag" part, except that it is still firing the 'click' event after dragging the element and it shouldn't.

again: element clicked - one event, click and hold - element is draggable (even after mouse up) and when clicked again it's back to normal (undraggable) state.

I am not looking for a trivial solution, it has to be built using Rx.Observable or at least Bacon's streamEvent object

Thank you

iLemming
  • 30,282
  • 53
  • 181
  • 302
  • 1
    I've always wondered if there is a small *moving* leeway necessary for 'click-and-hold' and 'double-click'. My Apple Magic mouse is ultra-sensitive to the slightest tremors, or possibly I should cut down on the coffee. – Jongware Feb 24 '15 at 21:36
  • This functionality can be easily handed by keeping the mouse down over the object. During the mouse down event its movable (This is the default in many scenarios). Additionally, you could bind the double click event to allow the dragable state, with a blur type event to disable drag function. – Mike Feb 24 '15 at 22:10
  • 2
    @Epik Basically if I asked a question: "how to calculate a volume of a pyramid" you said: "sum of the angles of any triangle is always equal 180 degrees". Yeah, I guess your comment is helpful, but I am not sure exactly how – iLemming Feb 24 '15 at 22:18

2 Answers2

6

I think you were pretty close with your solution, but probably it is not possible to elegantly achieve what you want while using the browser's built-in click event.

HERE is my attempt to tackle your problem.

The main idea is to define your own click streams like so:

var clicks = downs.flatMapLatest(function(){
  return ups.takeUntil(Rx.Observable.timer(250));
});

var longDownsStart = downs.flatMapLatest(function(){
  return Rx.Observable.timer(1000).takeUntil(ups);
});

In case of clicks we wait max 250 ms after a mouse down for a mouse-up; in case of the latter we generate the event only if there was no mouse-up within 1000 ms.

There might be some corner cases in which the code does not work as intended.

artur grzesiak
  • 19,110
  • 5
  • 43
  • 54
  • You can simplify the clicks stream by using `ups.takeWithTime(250)` instead of `ups.takeUntil(Rx.Observable.timer(250))` – paulpdaniels May 22 '15 at 16:37
2

Here is my proposed solution (with Bacon.js).

JJuutila
  • 361
  • 1
  • 4
  • 3
    Hard to upvote an answer that is just a link to the answer...try using the snippet functionality of SO, or at least post the important part of the solution like the other answer does – Brandon Feb 26 '15 at 11:40