var el = document.getEle mentById('contD iv');
addEventHandler (el, 'drag', test);
addEventHandler (el, 'mouseup', test);
document.getEle mentById('contD iv').onmousedow n=test;
addEventHandler (el, 'mousedown', test);
addEventHandler (el, 'mouseover', test);
Now it works in FF and IE.
WHY ?
This is a complicated problem with two overlapping issues here. So
sorry, but some long reading ahead.
Part 1 : Drag Confidential
There is undocumented system-level event in each browser
$MouseDragAtomi cUnit - I placed $ sign before the name to stress out
its internal nature plus the possibility to be called different names
in C++ source code. So do not search for it on MSDN, MDC, W3C or
particular engine's specs. The same $naming $convention further.
It is the fallback option for $MouseSelectDis creteUnits which is
checked first.
Say you started to drag some object - thus pressed down (left) mouse
button and started to move your mouse in any direction without
releasing the button.
1) First the system gets the object where the mouse was pressed.
2) Then it checks object's $AtomicSelectio n property. If true then go
to step 4 (your case)
3) If false then this object consists of discrete units which can be
selected individually: say block of text. In such case the system
checks if $MouseSelectDis creteUnits action is possible to the direction
of mouse move. If yes, then the selection starts.
4) If $AtomicSelectio n is true then the whole object gets selected and
$MouseDragAtomi cUnit starts. Unlike in Flash you are not allowed to
move displayed elements across the page by mouse means. You can only
implement such behavior via your own scripting. Thus
$MouseDragAtomi cUnit gets flag $notAllowed and respectively mouse
pointer changes to "not-allowed" shape. Yet the action itself is not
cancelled until the mouse released. This is because you may drag out of
the active window boundaries and release your mouse on some other
recipient: desktop or other application window. In such case if not
prohibited by security settings and if OLE supported a reference to
dragged object will be passed to recipient. This is how documents
scraps and other interesting things are being made. This way
$MouseDragAtomi cUnit has little practical sense within browser window -
it is almost always not-allowed - but it has big practical sense
overall.
The problem is that browser and specs producers seems mistook dragging
for some nasty sexual perversion :-) : in ten years no one dared to
describe the exact dragging mechanics so developers, generation by
generation, are forced to re-discover it on their own problems. - And
yes, back in 1998 I myself just like your was hitting my head over the
wall why dragging <layereither working or giving me crossed circle in
seemingly random order.
Part 2 : Killing Kenny
In order to bypass this obstacle in programmed dragging we have to tell
to the system in advance that this or that event is not what she thinks
it is. Particularly we have to warn the system that by pressing mouse
button down we are expressing _no_ intention to select something or to
use OLE dragging.
W3C and Microsoft ways to override default event behavior are
completely different, so to make cross-scripting not so painful it was
agreed to implement common shortcut: if event handler returns false
then it means "call $preventDefault EventAction subroutine" however it
is really implemented on this or that browser.
So when you have:
document.getEle mentById('contD iv').onmousedow n=test;
and test() has
return false;
then you call $preventDefault EventAction for mousedown event which
otherwise would be "wait for click, select or drag".
But if you are using addEventListene r / attachEvent methods then return
false; shortcut doesn't work anymore. It happens because in this case
there are not caller->callee relations where callee could return
something to its patiently waiting caller. Instead you have system
event dispatcher that notifies listeners one by one from its table.
System event dispatcher doesn't care what notified listener will do,
what will it return or if it returns anything. It notifies one and
moves to other right away.
It is also important that Gecko event dispatcher stores registered
listeners in internal array while IE in internal hash table. That means
that registered listeners on Gecko will be notified in order they were
added, while in IE they will be notified in an "organized disorder"
imposed by the internal hash storage mechanics.
This way you have two options to choose from in your particular case: a
bad one and a good one. I'll start from the good one :-)
1) You drop addEventListene r/attachEvent all together because in your
case they are not implied by the program logic, they do not add any
simplicity, portability or reliability. Use instead explicit event
handlers and return false; in them to prevent default actions.
2) You keep using addEventListene r/attachEvent. In this case you cannot
use the universal return false; shortcut. Instead you have to use then
underlying browser-specific tools. For Gecko it will be
EventObject.pre ventDefault(); method and for IE
event.returnVal ue=false; property change.