Same great maps plus a SLA, support, and control over ads
JavaScript within the browser is event driven, meaning that JavaScript responds to interactions by generating events, and expects a program to listen to interesting events. The event model for the Google Maps API V3 is similar to that used in V2 of the API, though much has changed under the hood. There are two types of events:
property_changed conventionEach Maps API object exports a number of named events. Programs interested in certain
events will register JavaScript event listeners for those events and execute
code when those events are received by registering addListener() event handlers on the
google.maps.event namespace. Developers of V2 of the Google Maps API will
be familiar with this usage.
For a complete list of events, consult the Maps API Reference. Events are listed in a separate section for each object which contains events.
Some objects within the Maps API are designed to respond to user events
such as mouse or keyboard events. A google.maps.Marker object
can listen to the following user events, for example:
'click''dblclick''mouseup''mousedown''mouseover''mouseout'These events may look like standard DOM events, but they are actually part of the Maps API. Because different browsers implement different DOM event models, the Maps API provides these mechanisms to listen for and respond to DOM events without needing to handle the various cross-browser peculiarities. These events also typically pass arguments within the event noting some UI state (such as the mouse position).
MVC objects typically contain state. Whenever an object's property changes, the
API will fire an event that the property has changed. For example, the API will fire
a zoom_changed event on a map when the map's zoom level changes. You can
intercept these state changes by registering addListener() event
handlers on the event namespace method as well.
User events and MVC state changes may look similar, but you generally wish to
treat them differently in your code. MVC events, for example, do not pass
arguments within their event. You will want to inspect
the property that changed on an MVC state change by calling the appropriate
getProperty method on that object.
You register for event notifications using the addListener() event
handler. That method takes an object, an event to listen for, and a function to
call when the specified event occurs.
The following code mixes user events with state change events. We attach an
event handler to a marker that zooms the map when clicked. We also add an event
handler to the map for changes to the 'zoom' property and move the map to Darwin,
Northern Territory, Australia on receipt of the zoom_changed
event:
var map;
function initialize() {
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var myOptions = {
zoom: 4,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'zoom_changed', function() {
setTimeout(moveToDarwin, 3000);
});
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title:"Hello World!"
});
google.maps.event.addListener(marker, 'click', function() {
map.setZoom(8);
});
}
function moveToDarwin() {
var darwin = new google.maps.LatLng(-12.461334, 130.841904);
map.setCenter(darwin);
}
View example (event-simple.html)
Note: If you are trying to detect a change in
the viewport, be sure to use the specific bounds_changed event
rather than constituent zoom_changed and center_changed
events. Because the Maps API fires these latter events independently,
getBounds() may not report useful results until after the viewport
has authoritatively changed. If you wish to getBounds() after such
an event, be sure to listen to the bounds_changed event instead.
UI events within the Google Maps API V3 typically pass an event argument, which
can be accessed by the event listener, noting the UI state when the event occurred.
For example, a UI 'click' event typically passes a Mouse event
containing a latLng property denoting the clicked location on the map
and a pixel argument denoting the screen coordinates of the clicked location.
Note that this behavior is unique to UI events; MVC state changes do not pass arguments in
their events.
You can access the event's arguments within an event listener the same way you would access an object's properties. The following example adds an event listener for the map, and creates a marker when the user clicks on the map at the clicked location.
var map;
function initialize() {
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var myOptions = {
zoom: 4,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
}
function placeMarker(location) {
var clickedLocation = new google.maps.LatLng(location);
var marker = new google.maps.Marker({
position: location,
map: map
});
map.setCenter(location);
}
View example (event-arguments.html)
When executing an event listener, it is often advantageous to have both private and persistent data attached to an object. JavaScript does not support "private" instance data, but it does support closures which allows inner functions to access outer variables. Closures are useful within event listeners to access variables not normally attached to the objects on which events occur.
The following example uses a function closure in the event listener to assign a secret message to a set of markers. Clicking on each marker will review a portion of the secret message, which is not contained within the marker itself.
var map;
function initialize() {
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var myOptions = {
zoom: 4,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// Add 5 markers to the map at random locations
var southWest = new google.maps.LatLng(-31.203405,125.244141);
var northEast = new google.maps.LatLng(-25.363882,131.044922);
var bounds = new google.maps.LatLngBounds(southWest,northEast);
map.fitBounds(bounds);
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 5; i++) {
var location = new google.maps.LatLng(southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random());
var marker = new google.maps.Marker({
position: location,
map: map
});
var j = i + 1;
marker.setTitle(j.toString());
attachSecretMessage(marker, i);
}
}
// The five markers show a secret message when clicked
// but that message is not within the marker's instance data
function attachSecretMessage(marker, number) {
var message = ["This","is","the","secret","message"];
var infowindow = new google.maps.InfoWindow(
{ content: message[number],
size: new google.maps.Size(50,50)
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
}
View example (event-closure.html)
None of the MVC state change events in the Maps API event system pass
arguments when the event is triggered. (User events do
pass arguments which can be inspected.) If you need to inspect a property
on an MVC state change, you should explicitly call the appropriate
getProperty() method on that object. This
inspection will always retrieve the current state of the MVC
object, which may not be the state when the event was first fired.
Note: explicitly setting a property within an event handler which responds to a state change of that particular property may produce unpredictable and/or unwanted behavior. Setting such a property will trigger a new event, for example, and if you always set a property within this event handler, you may end up creating an infinite loop.
In the example below, we set up an event handler to respond to zoom events by bringing up an info window displaying that level. We also check whether the map is fully zoomed-out and zoom in to zoom level 17 if so.
var map;
function initialize() {
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var myOptions = {
zoom: 4,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var zoomLevel;
var infowindow = new google.maps.InfoWindow(
{ content: 'Zoom Level Test',
size: new google.maps.Size(50,50),
position: myLatlng
});
infowindow.open(map);
google.maps.event.addListener(map, 'zoom_changed', function() {
zoomLevel = map.getZoom();
infowindow.setContent("Zoom: " + zoomLevel);
if (zoomLevel == 0) {
map.setZoom(10);
}
});
}