On 27 Jun 2006, at 21:46, Peter Michaux wrote:
> Have you tested that this is actually noticable or a problem? I'm
> interested if it impacts user experience by slowing things down. I
> without much difficulty.
Where it becomes noticeable is when you actually add several hundred
items to the DOM. The additional time required to add the necessary
properties to each item and initialise them does mount up.
>>>> It seems far better to have a single dragdrop manager
>>>> observing mouse events for the entire window, and simply
>>>> whether a clicked item is draggable by checking for a CSS class in
>>>> that item.
>>> You then have to loop through the registered draggable items to
>>> determine to which draggable object this element belongs. I'm
>>> any looping of this kind.
>> No looping involved. A draggable item has the style 'draggable'.
>> handles have the style 'draghandle'. When a mousedown event occurs,
>> simply check that the event target has the style 'draghandle'. If
>> not, do nothing. If it does, then walk up the DOM tree using
>> parentNode looking for the first item with the style 'draggable'. It
>> could actually be the hit item, of worst case two or three levels up
>> the tree. Of course, you could add other properties to items to flag
>> them as draggable, but I feel that using CSS styles has an advantage
>> in that a) we are testing a property that is already easily checked
>> in all DOM objects, and b) we can do fancy things like automatically
>> change the cursor or the item appearance if we hover over a
>> item with no extra code required.
> have a multi element draggable or an external handle? You could enter
> some sort of special class name scheme to identify which elements go
> together. Difficult to manage. You would need to do a find by
> classname for the entire dom at the begining of a drag to move all the
> parts of the multi element draggable.
inflated with additional code and properties. Not sure what yoou mean
by an external handle. The drag handle is outside of the object?
Weird. How does the user know where to click to drag an item? I need
an example of this.
I have no problem at all with dragging multiple items. Before you
drag stuff, you need to select it, so you must already have a
container in place that manages item selection. That container is
aware which items are selected, and therefore does not need to do any
searching of the DOM. Incidentally, Prototype.js already has a
function that will find elements by class name given a starting
position in the DOM e.g the container which deals with item
selection, say, a list. If you are coding a drag and drop list, I
can't think of an instance where the list of selectable items would
be any different from the list of draggable items, so once you have
selection sorted, you simply drag what is selected.
Incidentally, I refer to the 'list' repeatedly as a form of
shorthand for "a DOM container that may contain any number of items
that may be selected and dragged".
> I think there is a lot of strength having objects represent the
> draggables. This also separates display from behavior as class names
> can be reserved for display only.
I see your point, but CSS already provides means of providing visual
feedback when hovering over an item that can perform an action, so in
many cases you already assign special styles to drag handles so that
you can highlight the item or change the cursor to indicate that
something magical will happen if you click there. I simply detect
this style as a means of identifying a draggable item.
I think there is a slight flaw in your argument about separating
display from behavior, in that draggable DOM elements have no
behavior. They are simply display elements. The behavior is the
function of the enclosing list container. Only the list knows what to
do when the user clicks an item.
> Without registration, how will do do targetable affordance? In my
> donut example all the legal targets turn yellow at the drag start.
> Will you do a find by two multiple names thorough the entire DOM? Look
> for elements with class names for the correct interaction groups that
> also have the class name "target"? Perhaps targetable affordance is
> not a big deal for you but it is an example of the flexability when
> objects represent draggables and targets.
Targetable affordance is easy in the model I propose. It is the job
of the drop target to highlight if the current drag is acceptable to
the target. The target can simply listen for a custom event broadcast
by the drag manager at the start of a drag. "Hey everyone! I'm
dragging some items that have pictures in them. hands up all targets
who like pictures!" "Ooooh! Me! Me! Me! Pick Me!"
> Is it really noticable in performance? It is not all replication as
> the draggable object knows all of it's individual parts, interaction
> groups etc. Using class names for this has to be slower at times than
> keeping caches of registered draggables or targets in particular
Not slow at all. Like I said before, we already know what items are
draggable because we selected them in the first place. Besides, if
our list object detects a mousedown event on an element, it is
trivial to check to see if it has the class name 'draghandle'. If so,
it simply looks up the DOM a level or two at most to findd the item
that has the class name 'dragggable'. You can create a 'draggable'
div and nest as many items in it as you wish, and make any thing a
drag handle. Hey, if the outer div has no visible border or
background, you can even create the effect of an external drag
handle, whatever that is.
> I've been thinking that it might be more harmful than good to try to
> do things the way a desktop os does things. The OS knows much more
> than the browser does. Also the OS can do everything much faster than
> at OS dragdrop is not a bad idea.
If you are dragging multiple items, all of which are carrying drag
and drop code, are you calling each in turn to handle the drag? With
a single drag manager, any number of items can be dragged with no
extra code. Once we have our list of items being dragged, we dump
clones of them into your doughnut and off we go. In fact, now that I
think about it, we could actually create the clones once when we
detect a draggable item and store refs to them in the draggable. When
we want to drag an item we have a ready-rolled clone stashed in a
property that we can dump into the doughnut proxy. That would speed
things up at the start of the drag, but may slow things down
elsewhere, as well as consuming memory for every item whether it will
be dragged or not.
> How would you make an insertion point indicator so the user knows
> where the drop will take place? With a styled HTML list, this is
> tricky to do in an efficient way.
Well, when we start dragging doughnuts around, the drop target
displays an insertion point when it see the mousemove event and
determines that it can handle the drop.
> Inefficient code in my method seems like your main concern and I would
> be very interested if you've experience this as a real problem. I
> think any minor inefficency in object creation will be balanced by
> greater efficiency during the drag drop operations. But this is
Of course, I dislike inefficient code as much as the next person, but
that is not my main concern, I have looked at several models for drag
drop implementations in JS, and they all add code to draggable items.
OS implementations never do this, and the guys who write OS'es have
spent many years looking at this, and all tend to lean towards a
global drag manager. This makes sense as every item is then
potentially draggable, with minimal additional effort on the part of
the programmer. User clicks on an item and program says to the drag
manager, "Drag this for me please". Nothing is special about the
item. I just go a step further and flag items as with class names as
it is convenient to do with CSS, and adds very little baggage.
What I'm trying to suggest is that we draw logical boundaries around
distinct functions in the interface. All the examples I have seen so
far support drag and drop in a very limited fashion, in that
draggable items are never selected *before* the user clicks them. You
click, you drag, you drop. In reality, you want to select an
arbitrary number of items first, so we need an object that can
maintain a selection of items. This is our list.
When the list detects a mouse movement with the button depressed
within any of it's selected items, it can hand the job over to the
drag manager. At no point is there any requirement for an item to
know that it is being dragged, or for the item to take any special