Los mismos mapas de excelente calidad, además de un acuerdo de servicio, asistencia y control sobre los anuncios.
En el navegador, JavaScript está orientado a eventos, lo que significa que JavaScript responde a las interacciones generando eventos y espera que un programa detecte los eventos interesantes. Por ejemplo, en los navegadores, las interacciones del usuario mediante el teclado y el ratón crean eventos que se propagan en el DOM. Los programas interesados en determinados eventos registran detectores de eventos JavaScript para dichos eventos y ejecutan código al recibirlos.
El API de Google Maps interactúa con este modelo de eventos definiendo eventos personalizados para los objetos del API. Es importante tener en cuenta que los eventos del API de Google Maps son distintos de los eventos DOM estándar y están separados de ellos. No obstante, dado que los distintos navegadores implementan distintos modelos de eventos DOM, el API de Google Maps también ofrece mecanismos de detección y respuesta a estos eventos DOM sin necesidad de gestionar las numerosas peculiaridades de cada plataforma.
Los eventos del API de Google Maps se gestionan mediante funciones de utilidades en el espacio de nombres de GEvent para registrar los detectores de eventos. Cada objeto del API de Google Maps exporta una determinada cantidad de eventos con nombres. Por ejemplo, el objeto GMap2 exporta los eventos click, dblclick y move, entre muchos otros. Cada evento se produce en un contexto determinado y puede pasar argumentos que identifiquen dicho contexto. Por ejemplo, el evento mousemove se activa cuando el usuario mueve el ratón sobre un objeto de mapa y transmite el objeto GLatLng de la ubicación geográfica en la que se encuentra el ratón.
Para acceder a una lista completa de eventos GMap2 y los argumentos que generan, consulta GMap2.Events.
Para registrar la notificación de estos eventos, utiliza el método estático GEvent.addListener(). Este método toma un objeto, un evento que debe detectar y una función a la que debe llamar cuando se produzca el evento especificado. Por ejemplo, este fragmento de código muestra una alerta cada vez que el usuario hace clic en el mapa:
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
GEvent.addListener(map, "click", function() {
alert("You clicked the map.");
});
Ver ejemplo (event-simple.html)
Los detectores también pueden capturar el contexto del evento. En el siguiente código de ejemplo, mostramos la latitud y la longitud del centro del mapa después de que el usuario lo arrastre.
var map = new GMap2(document.getElementById("map"));
GEvent.addListener(map, "moveend", function() {
var center = map.getCenter();
document.getElementById("message").innerHTML = center.toString();
});
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
Ver ejemplo (event-context.html)
Al ejecutar un detector de eventos, suele ser recomendable disponer de datos privados y persistentes adjuntos a un objeto. JavaScript no admite datos de instancias privadas, pero sí admite cierres, lo que permite que las funciones internas accedan a variables externas. Los cierres resultan útiles en los detectores de eventos para acceder a variables que normalmente no están adjuntas a los objetos en los que se producen los eventos.
En el siguiente ejemplo se utiliza un cierre de función en el detector de eventos para asignar un mensaje secreto a un conjunto de marcadores. Al hacer clic en cada marcador se revisa una parte del mensaje secreto, que no está incluido en el propio marcador.
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
// Creates a marker at the given point
// The five markers show a secret message when clicked
// but that message is not within the marker's instance data
function createMarker(point, number) {
var marker = new GMarker(point);
var message = ["This","is","the","secret","message"];
marker.value = number;
GEvent.addListener(marker, "click", function() {
var myHtml = "<b>#" + number + "</b><br/>" + message[number -1];
map.openInfoWindowHtml(point, myHtml);
});
return marker;
}
// Add 5 markers to the map at random locations
var bounds = map.getBounds();
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 < 5; i++) {
var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random());
map.addOverlay(createMarker(point, i + 1));
}
Ver ejemplo (event-closure.html)
Muchos eventos del sistema del API de Google Maps pasan argumentos al activarse. Por ejemplo, el evento "click" de GMap2 transmite los argumentos overlay y overlaylatlng si el clic de mapa se produce en una superposición; de lo contrario, transmite un argumento latlng de la coordenada del mapa. Puedes acceder a estos argumentos pasando los símbolos especificados directamente a las funciones de los detectores de eventos.
En el ejemplo anterior, primero realizamos una prueba para asegurarnos de que el clic se realizó en un mosaico de mapa comprobando si se ha definido el argumento latlng; en tal caso, abrimos una ventana de información sobre la coordenada en la que se ha hecho clic y mostramos la coordenada convertida en espacio de píxeles junto con el nivel de zoom.
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
GEvent.addListener(map,"click", function(overlay, latlng) {
if (latlng) {
var myHtml = "The GPoint value is: " + map.fromLatLngToDivPixel(latlng) + " at zoom level " + map.getZoom();
map.openInfoWindow(latlng, myHtml);
}
});
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
Ver ejemplo (event-arguments.html)
Las funciones resultan útiles cuando se desea adjuntar detectores de eventos a instancias concretas de un objeto. Si en lugar de ello quieres invocar un método sobre todas las instancias de un objeto como respuesta a determinados eventos, puedes utilizar GEvent.bind(). En el siguiente ejemplo, una instancia de clase de aplicación vincula eventos de mapa a sus propios métodos, modificando el estado de la clase cuando se activan los eventos:
function MyApplication() {
this.counter = 0;
this.map = new GMap2(document.getElementById("map"));
this.map.setCenter(new GLatLng(37.4419, -122.1419), 13);
GEvent.bind(this.map, "click", this, this.onMapClick);
}
MyApplication.prototype.onMapClick = function() {
this.counter++;
alert("You have clicked the map " + this.counter + " " +
(this.counter == 1 ? "time" : "times"));
}
var application = new MyApplication();
El modelo de eventos del API de Google Maps crea y gestiona sus propios eventos personalizados. No obstante, el DOM también crea y utiliza sus propios eventos, según el modelo concreto de eventos que utilice el navegador. Si deseas capturar y responder a estos eventos, el API de Google Maps proporciona contenedores independientes del navegador para detectar y vincular los eventos DOM sin necesidad de emplear código personalizado.
El método estático GEvent.addDomListener() registra un gestor de objetos para un evento DOM en un nodo DOM. De forma similar, el método estático GEvent.bindDom() permite registrar gestores de eventos para eventos DOM de instancias de clases.
Cuando un detector de eventos deja de ser necesario, es conveniente eliminarlo. Esto puede ser necesario incluso en los casos en los que el evento sólo se deba activar una vez. La eliminación de detectores de eventos definidos mediante funciones anónimas entre cierres puede ser difícil. No obstante, las funciones addListener(), addDomListener(), bind() y bindDom() devuelven una instrucción GEventListener, que puede emplearse para anular el registro del gestor en un momento determinado.
El código del siguiente ejemplo responde a un clic colocando un marcador en el mapa. A partir de ese momento, cualquier clic adicional elimina el detector de eventos. Observa que, en consecuencia, el código removeOverlay()nunca se ejecuta. Observa también que puedes eliminar un detector de eventos desde el propio detector en cuestión.
function MyApplication() {
this.counter = 0;
this.map = new GMap2(document.getElementById("map"));
this.map.setCenter(new GLatLng(37.4419, -122.1419), 13);
var myEventListener = GEvent.bind(this.map, "click", this, function(overlay, latlng) {
if (this.counter == 0) {
if (latlng) {
this.map.addOverlay(new GMarker(latlng))
this.counter++;
} else if (overlay instanceof GMarker) {
this.removeOverlay(marker)
}
} else {
GEvent.removeListener(myEventListener);
}
});
}
function load() {
var application = new MyApplication();
}