The Mousepoint Event
The mousepoint event is the first half of the point-and-click gesture. The event occurs when the mouse stops moving and points to a new target. This event is preferable to the mouseover event for use in heavily populated tool tips and nested menus, since use of the mouseover event can cause a flurry of unintended activity as the mouse crosses over irrelevant material before getting to a desired element or menu. This web page presents a demo, specification, and multi-browser implementation of the mousepoint event; a discussion of related work is included at the end.
The mousepoint event in action
As with other events, one can specify that events associated with containing parent elements are handled before events associated with the smaller elements they contain, allowing one to drill down from the general to the specific. For example, pointing to the word "penguins" in the following sentence allows one to drill down via use‑capturing event handlers that underline the sentence, its trailing conjunct, and the word penguin, in that order, with the underline for "penguin" coming out on top:
Birds fly, but not penguins
Here is the same sentence with event bubbling in place of event capturing:
Birds fly, but not penguins
The + or − signs mark the success or refusal of the co-events used to restore elements to a previous state. See co-event discussion below.
The mousepoint event fires when the mouse moves from one element to another and stops. By definition, the properties and methods of the mousepoint event include all of the standard mouse event fields. The relatedTarget field holds the target of the previous mousepoint event, if there was one, and is null otherwise. Notice that the relatedTarget and target fields are never equal, as the mousepoint event occurs only when pointing to a new target.
The sequencing of the mousepoint event relative to other mouse events is as follows:
mouseover → mousepoint → mousedown → mouseup → click → mouseout
Mousepoint co-events. Mouse events tend to occur in co-event pairs, with the second event undoing what the first accomplished. For example, a mouseout event might undo the effect of a mouseover. In this document, mousepoint serves as its own co-event. The above logging function illustrates this phenomenon by logging the "undo" functions used to restore elements after a given mousepoint has passed on to the next mousepoint.
In the application script for this document, there is a single generic mousepoint coEventHandler that manages a relevantCoEvent stack. If the effect of a given mousepoint event is to be undone at a future mousepoint event, an event-specific undo function is pushed onto the relevantCoEvent stack when the given event fires. At the beginning of the next mousepoint event, the coEventHandler calls each undo function on the relevantCoEvent stack. If the undo function considers the call to be premature, it refuses to act, and the coEventHandler returns the undo function to the relevantCoEvent stack.
The logger traces the coEventHandler indirectly by tracing the undo functions it calls and by attaching a + or a − according to the response of the undo function. These traces clearly show that the coEventHandler has achieved simplicity at the expense of redundant behavior.
As should be plain from the above simple examples and the accompanying code at the end of this page, it is indeed possible to implement mousepoint as a user-defined event and to then attach event listeners in the usual way. Moreover, the dispatched mousepoint event does contain all of the event information one would expect from a mouse event. However, there are some glitches.
1. HTML event assignment. The tag <p onmousepoint="doSomething"> is not valid HTML because the known event names were immutably hardwired into HTML prior to the introduction of user-defined events.
2. Element property assignment. The ability to assign new properties to HTML objects is under attack from standards bodies, in direct conflict with assignments of the form element.onmousepoint = doSomething. The given implementation doesn't support this method of assigning event handlers.
3. Tracking the location of the cursor. The most efficient implementation strategy for detecting the mousepoint event would be to employ setIntereval to poll the locations of the cursor as it moves and then stops. But there appears to be no way of sensing the location of the cursor without waiting for user-initiated events.
The fall-back is to monitor the mousemove
events and then wait, via setTimeout, a half-second after they stop. This causes
a noticeable delay in recognizing the event. It also forces one
to repeatedly construct tentative mousepoint events in response to
each mousemove event, until the "real" one comes along.
4. No testing has been done on programmatic triggering of mousepoint events.
5. Accommodations for standards-based browsers. The script adds a global variable, an event object named mousepoint, that has been augmented with auxiliary methods pertaining to the mousepoint event. This variable is itself not part of the specification.
The initial implementation relied on a single mousepoint event that was reinitialized and recycled. But when bubbling is cancelled on an event, Chrome and Safari disable the event in a way that isn't recoverable. To efficiently create a new event on each dispatch, the script uses a Mousepoint prototype that, in essence, is a subclass of the MouseEvent class.
Attempts to use prototypes to add standards compliant event-related methods have been going on for some time; Jason Karl Davis records a four-year pyrrhic victory at codeforum.com.
handler, useCapture) =
handler, useCapture) =
These mousepoint methods are redundant in the case of standards‑based browsers. Their advantage is that they also work in Internet Explorer.
This is a fairly tall claim. The IE fireEvent method
analogous to dispatchEvent doesn't support programmer-supplied event
names — and lots of others
doesn't support the event.currentTarget attribute. IE doesn't support useCapture. In view of these
hurdles, the implementation builds IE's mousepoint event methods
largely from scratch rather than relying on IE's event handling
In addition to programmer supplied names such as onmousepoint, fireEvent also returns the Invalid Argument error for twenty predefined names: onabort, onafterprint, onbeforeprint, onbeforeunload, onbounce, onchange, onerror, onfinish, onhashchange, onload, onmessage, onoffline, ononline, onreset, onselect, onselectionchange, onstart, onstop, onsubmit, and onunload.
7. Accommodations for Internet Explorer 9. This was a relative breeze, with only one hitch. The IE9 .initMouseEvent method won't allow the related-target field to be undefined, so now the first relatedTarget is null instead.
The logger needs to know the names of the functions it logs, or in the case of anonymous functions, the name of their function factory. Initially, I just attached the name to the function itself, believing that such "first-class objects" must have have attributes. That worked fine in Firefox and Internet Explorer, but, especially in the case of anonymous functions, not Opera, Chrome, or Safari. So I assigned the name attributes to functions' prototype instead. That actually worked.
Opera often refuses to display the underlines in the birds fly example, and the problem has to do with the complexity of the example. However, the log function can be used to show that the mousepoint mechanism itself is not at fault and indeed is working correctly in Opera.
The mousepoint script used in this document has been successfully tested in Firefox 3.6.7, Internet Explorer 8.0.6001.187021C, Opera 10.60, Safari 5.0, and Chrome 5.0.375.99.
Background and Related work
The mousepoint event can be observed in the menus of any modern browser. In Firefox, for example, click on the View menu and scroll down to the sidebar item; what you don't see is the toolbars submenu because, although you probably moused over it, you didn't actually point to it.
At some time the WindowsXP operating system also switched from mouseovers to mousepoints for displaying menus, but the change was not accompanied by public fanfare or discussion.
As pointed out by azoomer, the mousepoint event is similar to the hoverintent jQuery plugin, but without depending on jQuery. However, as a jQuery event, hoverintent doesn't support the distinction between target and currentTarget, nor does it support use-capture semantics. As explained above, the implementation approach is also somewhat different.
Mouse gestures are currently an area of active development and research. Viewed as a gesture, the mouse-point event is arguably the most physically efficient, due to its emphasis on absence of motion.
Licensing and Copyright Information
Several other products and companies use the terms "mousepoint" or "mouse point." I am unaware of any connection between the present notion of a mousepoint event and these other endeavors. In most of these other cases, the term mouse point is used as a shorthand for mouse cursor location. I invite discussion and further contributions to this idea and would be happy to coauthor improvements.
2010. The Mousepoint Event by Jim Williams is licensed under a Creative Commons Attribution License; the corresponding mousepoint script is available under the GNU General Public License, version 3.0 or later.
Version of 3/19/2011