December 11th, 2008
The Google Maps API and Mouse Cursors
While working on a project using google maps, I needed to control the mouse cursor to help indicate which of several tools was active (much like many popular applications such as the Adobe tools and various CAD packages do for example). Unfortunately Google does not provide a way (and certainly not a documented way) to control the cursor over the map aside from during drag and drop.
Outside of the google maps world, setting the cursor is easy. You simple add the “cursor:some-cursor” property to some css that applies to that element or place it in the DOM elements style.cursor property. In the google world it isn’t quite so straight forward.
You can do something as simple as:
#gmapDiv {
cursor:some-cursor !important;
}
As a side note, the “!important” in general since the api sets the cursor on numerous elements via the DOM properties.
The results are not really desirable though. Whatever cursor you set now applied to everything in the map container div, including the controls. In most cases that isn’t what is wanted. In my case, I only wanted the special cursor to appear when the mouse was over the actual map tiles, but not the controls.
Because google has not made any special effort to class DOM elements inside the map container div, creating a selector that does what is needed is a bit difficult and probably won’t work in every browser (particularly older IE). In any case, it works in the current version of firefox (3) and should work in any browser that supports the pseudo selector “:first-child”.
#gmap.turnOnMyCursor > div:first-child > div:first-child {
cursor:crosshair !important;
}
As of this writing, the map tiles are all contained within the first child div of the first child div of the map container. This div has included in its DOM style properties “cursor:-moz-grab” on firefox.
You could simulate this in a less browser specific way (or at least a way that isn’t so sensitive to each browsers CSS implementation) using the DOM and javascript to select the actual element that needs the cursor. Using prototype you would do something like this:
/* CSS Snippet */
#gmap .tornOnMyCursor {
cursor:some-cursor;
}
/* Javascript Snippet */
$("gmap").chileElements()[0].childElements()[0].addClassName("turnOnMyCursor");
One undesirable side effect this creates is the the API is no longer able to set the map dragging cursor when the user grabs the map and drags. The css style with “!important” overrides the element style set in the DOM by the API.
Originally, I tried dealing with the cursor by setting DOM element style.cursor properties. As I discovered, this will not work in general. The api’s event code resets the DOM style properties very often so changes in the cursor made via the DOM properties only survive until the next event. By placing them in a css style block with a selector you can easily control which cursor is used by adding and removing classes from the map container, or optionally from the tile pane.
Leave a Reply
You must be logged in to post a comment.