HM utilizes multiple mouse-related events of Web pages to control the display
and behavior of the menus themselves. The common mouseover and mouseout
events, for example, are used to trigger the display of child menus when parent menu items
are rolled over. The click event is utilized to trigger the display of a new menu
or the following of a link from a menu item, depending on the configuration of the menus
themselves. And the mousedown and mouseup events are used in conjunction
with tall scrolling menus, allowing the user to scroll the menus by holding the mouse down
on the scrollbars. We didn't run into any problems with Opera's implementation of the
mouseover, mouseout, and click events; but the latter two items,
mousedown and mouseup, did pose some difficulties.
We've tied two event handlers to the mouseup and mousedown
handlers of this Web page. These handlers print a message in the form textarea box below;
printing "Mouse is Down" for the mousedown event; and "Mouse is Up" for the
mouseup event. Try clicking and releasing your mouse on this page (but not
over links, of course, since you will then exit the page) to see how your browser responds to these
events. (Most browsers will work with this example, but some older browsers may not).
In most browsers, the behavior is what you expect: click the mouse down,
get a mouse down message; release the mouse, get a mouse up message. In Opera 7 this is also
the case, but with one notable exception: if you click and then drag the mouse
over selectable text (or a form input field which supports select events) then no mouseup
is provided when the mouse is released. Try it, selecting some text from this paragraph.
In Opera 7, no mouseup message is received; in other browsers supporting the mousedown
and mouseup events, a mouseup is still received following the release of the mouse
(and the selection of the actual text). At this moment, we don't know what's happening with
the mouseup; whether it's not firing at all or is being canceled at an extremely low
level of the document (the text nodes themselves, for example) such that it never bubbles
up to the document level.
Either way (for HM), we weren't initially concerned with this
issue, as the only time we look for mouseup events is when the user scrolls a scrollable
menu; and at that point the mouse is over a scroll bar (at least initially) so we know
we aren't over selectable text. Or do we?
It turns out this problem is actually quite tenacious. Consider the example
of the box below, similar to our box from the previous page:
This time we attached the mousehandlers directly to the inner div
of the example (within the red border). Click your mouse within the white area of
the box. Again, if the mouse does not move, then the mousedown and mouseup
are reported as expected. If you do move the mouse, however, typically no mouseup is
reported. Why? Presumably because the browser "sees" the text beneath the red
bordered box (i.e., the "aaa bbb ccc..." text) and begins selection of that text, canceling
the mouseup in the same manner as above--even though that text is not visible to the user.
To confirm this, set up your own test with the box above, but remove the text in the outer div.
You will find that the mouseup and mousedown then behave predictably; you can
move the mouse within the white box while the mouse button is down and still receive the
mouseup message when you release it.
Another way to trigger the problem is to move an element with text
beneath the element the mouse handlers are assigned to. In this scenario, the
user does not even have to move the mouse after pressing the mouse button; the text that
moves beneath the mouse itself triggers the select action, canceling the mouseup
event. As in the above example, it doesn't matter if the user can see the actual text
that is moving, so long as it's in an element of the page that is not itself
explicitly hidden (really "hidden," as opposed to simply covered by
another element in higher z-order).
In HM, the result of all of this is the triggering of two potential problems,
both of which can occur when scrollable menus are displayed:
Once a menu begins scrolling, it may not stop until it reaches its ultimate top or
bottom item. This is because we're looking for the document's mouseup to trigger the stop
action for the scroller, which may never occur; either because the text of the menu
items themselves trigger the select action as they scroll beneath the mouse, or
because the user inadvertently moves the mouse while on the scroll bar and the scroll
bar happens to appear over in-page text.
As menu items pass beneath the scroll bar, the text of the menu items themselves may
appear as selected items; indeed, this selection may even carry over to elements
of the actual HTML page itself, depending on the positioning of the scrolling menu
within the page.
Regrettably, we haven't discovered a graceful workaround for this
specific problem; and we suspect we'll have to disable scrolling menu support in Opera
entirely when we release version 5. On the next page, however, we discuss some
of the things we tried in an effort to work around the issue.