English | Site Directory

Google Mapplets

Mapplet Events

  1. Events Overview
    1. Event Listeners
    2. Event Closures
    3. Event Arguments
    4. DOM Events
    5. Removing Event Listeners

Mapplet Events Overview

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. For example, within browsers, user mouse and keyboard interactions create events that propagate within the DOM. Programs interested in certain events will register JavaScript event listeners for those events and execute code when those events are received.

The Google Mapplets API adds to this event model by defining custom events for Mapplet objects. It is important to note that the Mapplets API events are separate and distinct from the standard DOM events. However, as different browsers implement different DOM event models, the Mapplets API also provides mechanisms to listen for and respond to these DOM events without needing to handle the various cross-browser peculiarities.

Event Listeners

Events in the Mapplets API are handled by using utility functions within the GEvent namespace to register event listeners. Each Mapplets API object exports a number of named events. For example, the GMap2 object exports click, dblclick, and move events, and a host of others as well. Each event happens within a given context, and can pass arguments that identify that context. For example, the dragstart event fires when the user clicks and holds the mouse within a map object, and passes the GLatLng of the geographic location in which the mouse is located.

For a complete list of GMap2 events and the arguments they generate, see GMap2.Events.

To register for notification of these events, use the static method GEvent.addListener(). That method takes an object, an event to listen for, and a function to call when the specified event occurs. For example, this code snippet shows an alert every time the user clicks on the map:

var map = new GMap2();

GEvent.addListener(map, "click", function(marker, point) {
  if (marker) {
    map.removeOverlay(marker);
  } else {
    map.addOverlay(new GMarker(point));
  }
});

Run this example (event-simple.xml)

Listeners are also able to capture the context of the event. In the following example code, we display the latitude and longitude of the center of the map after the user drags the map.

var map = new GMap2();
GEvent.addListener(map, "moveend", function() {
  map.getCenterAsync(function(center) {
    map.openInfoWindowHtml(center, center.toString());
  });
});
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

Run this example (event-context.xml)

Using Closures in Event Listeners

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 sequential number values to a set of markers. Clicking on each marker will display a different value, which is not contained within the marker itself.

var map = new GMap2();

// Creates a marker at the given point with the given number label
function createMarker(point, number) {
  var marker = new GMarker(point);
  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml("Marker #" + number);
  });
  return marker;
}

// Add 10 markers to the map at random locations
map.getBoundsAsync(function(bounds) {
  var southWest = bounds.getSouthWest();
  var northEast = bounds.getNorthEast();
  var lngSpan = northEast.lng() - southWest.lng();
  var latSpan = northEast.lat() - southWest.lat();

  for (var i = 0; i < 10; i++) {
    var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
                            southWest.lng() + lngSpan * Math.random());
    map.addOverlay(createMarker(point, i + 1));
  }
});

Run this example (event-closure.xml)

Using Passed Arguments in Events

Many events in the Mapplets API event system pass arguments when the event is triggered. For example, the GMap2 "click" event passes two arguments (overlay,point) in the event. You can access these arguments by passing the specified symbols directly to the functions within the event listeners.

For example, the "click" event on a map passes an overlay and point argument. We pass these arguments directly within the callback function to invoke within the event listener.

Notice that we need to make two asynchronous requests in this example to retrieve the pixel coordinates and current zoom level. We use GAsync() to process these requests in parallel before we initiate the callback method based on those return values.

  var map = new GMap2();
  map.setCenter(new GLatLng(37.4419, -122.1419), 13);

  GEvent.addListener(map,"click", function(overlay,point) {
    if (point) {
      GAsync(map, 'fromLatLngToDivPixel', [point], 'getZoom', function(divPixel, zoom) {
        var myHtml = "The GPoint value is: " + divPixel + " at zoom level " + zoom;
        map.openInfoWindow(point, myHtml);
      });
    }
  });

Run this example (event-arguments.xml)

Listening to DOM Events

The Mapplets API event model creates and manages its own custom events. However the DOM also creates and dispatches its own events, according to the particular browser event model in use. If you wish to capture and respond to these events, the Mapplets API provides browser-neutral wrappers to listen and bind DOM events, without the need for custom code. Note that a mapplet can only listen to DOM events within its own <iframe>.

The GEvent.addDomListener() static method registers an event handler for a DOM event on a DOM node. Similarly, the static method GEvent.bindDom() allows you to register event handlers for DOM events on class instances.

Removing Event Listeners

When an event listener is no longer needed, you should remove it. This is especially important in Mapplets as the listeners introduce extra communication overhead. Removing event listeners that were defined via anonymous functions within closures can be difficult. However, the addListener(), addDomListener(), bind(), and bindDom() functions return a GEventListener handle, which can be used to eventually deregister the handler.

The following example responds to a click by placing a marker on the map. Any subsequent click removes the event listener. Notice that the removeOverlay() code is never executed as a result. Also, notice that you can remove an event listener even from within the event listener itself.

function MyApplication() {
  this.counter = 0;
  this.map = new GMap2();
  this.map.setCenter(new GLatLng(37.4419, -122.1419), 13);
  var myEventListener = GEvent.bind(this.map, "click", this, function(marker,point) {
    if (this.counter == 0) {
      if (point) {
        this.map.addOverlay(new GMarker(point))
        this.counter++;
      } else {
        this.removeOverlay(marker)
      }
    } else {
      GEvent.removeListener(myEventListener);
    }
  }); 
}
var application = new MyApplication();

Run this example (event-removal.xml)

Continue on to the Mapplet Overlays.