1

I have a slider a little like this:

             ________
------------|        |---------------------------------------
   :    <-- | slider | -->    :        :        :        :
------------|________|---------------------------------------

I'm using jQuery UI to make the slider draggable. This works fine.

The problem is that I'm executing a function each time the slider crosses a section boundary (indicated by :). This function takes approximately 30ms to execute (it's constructing a DocumentFragment and inserting it into the document). During this time the browser does not respond to events, so jQuery UI stops adjusting the slider's position and the drag is prematurely ended (the user is forced to release the mouse button and commence a new drag). This makes the slider feel jerky and buggy.

Is there a solution to this problem?

Edit: I've created a simple fiddle which demonstrates the problem. Note that while the drag is essentially paused during the execution of the slow function, it resumes afterwards. This makes me suspect that there's something about my more complex scenario which is causing the drag event to be cut short (perhaps the DOM manipulation is causing the position of the slider to change briefly).

Edit: After further investigation I'm much closer to understanding the problem. The DOM manipulation code contains a line something like $('.droppable').remove(). This removes the matching elements from the DOM after detaching any event handlers bound to them and removing any associated data. If I use .detach() instead, the behaviour is the same as in the simple fiddle above. Something untoward is happening during the cleanup.

davidchambers
  • 23,918
  • 16
  • 76
  • 105
  • Perhaps 100 elements. I'm testing in the latest stable version of Chrome (21). – davidchambers Aug 12 '12 at 19:29
  • Do you have to add the fragments in real time as the slider is dragged, or would it be acceptable to accumulate callbacks and calling them in sequence after the slider stopped moving for a given amount of time? – Frédéric Hamidi Aug 12 '12 at 19:31
  • That's actually the approach I'm taking, Frédéric. I don't generate or insert the DocumentFragment until I've determined that the user is interested in a particular section. I do this by calculating the speed of the drag, and doing nothing if the speed exceeds a certain threshold. The problem is that even if the mouse position is not changing, the function execution ends the drag event (I'm not sure whether this is specific to the way jQuery UI determines the end of a drag). – davidchambers Aug 12 '12 at 19:41
  • Can you post the code of the event handler that computes the speed threshold and calls the costly function? Also, does that function modify part of the slider widget in any way (option setter, method call, or direct DOM manipulation)? – Frédéric Hamidi Aug 12 '12 at 20:07

1 Answers1

0

I'd suggest to use jQuery's or Underscore's debounce function, or some equivalent method, to call the function just once every 100 or 200 ms or so.

This won't make things smooth, but at least they won't feel buggy.

Interesting article about it.

MaxArt
  • 22,200
  • 10
  • 82
  • 81