Make custom overlay clickable (Google Maps API v3)
Asked Answered
D

5

34

I have a custom overlay class (ImageOverlay) which inherits from google.maps.OverlayView. I want it to respond to Google Maps click events (not just DOM click events) but simply using addListener doesn't seem to do the trick.

e.g. I have a shapes array which contains a mixture of google.maps.Polygon and ImageOverlay objects:

for (var i in shapes) {
  google.maps.event.addListener(shapes[i], 'click', function(){alert('hi')});
}

Clicking on the polygons triggers an alert but clicking on the custom overlays does nothing.

How do I make Google Maps API treat the overlays as clickable?

Dynamics answered 29/7, 2010 at 11:9 Comment(0)
O
68

Update for v3: overlayLayer doesn't accept mouse events anymore. Add your overlay to overlayMouseTarget instead, add the listener, and it should receive mouse events normally.

//add element to clickable layer 
this.getPanes().overlayMouseTarget.appendChild(div);

// set this as locally scoped var so event does not get confused
var me = this;

// Add a listener - we'll accept clicks anywhere on this div, but you may want
// to validate the click i.e. verify it occurred in some portion of your overlay.
google.maps.event.addDomListener(div, 'click', function() {
    google.maps.event.trigger(me, 'click');
});

See: http://code.google.com/apis/maps/documentation/javascript/reference.html#MapPanes

Othella answered 14/9, 2011 at 10:13 Comment(5)
Thanks for this! Underdocumented. Made my day. Just to add, this is necessary with touch events too (i.e. not just "Mouse" input), especially on iOS.Sulphanilamide
After reading lots of blogposts and trying lots of code, this was the sollution I needed! Thanks!Selfsatisfied
Weird. They actually "fixed" this "feature" for a while, but it seems they have removed the fix!Heroin
I've implemented it in my application and it's working fine, thanks. But I have a related question. Is there any (elegant) way to manage when user is panning the map but he has clicked on the overlay? I wouldn't like to execute the onclick event when I just want to pan the map.Improvement
My question above has been answered here.Improvement
V
14

The Maps API can't automatically determine which portions of your overlay should be clickable (i.e. if you render an image with a transparent background, if would be up to your overlay class to determine whether clicks in the transparent region count as valid clicks or not).

You should add DOM listeners to the overlays you draw, and then trigger your own Maps API click event if this is a valid click.

Example:

FooBar.prototype.onAdd = function() {
  // Create a div and append it to a map pane. 
  var div = document.createElement('div');
  div.style = "height: 100px; width: 100px";
  this.getPanes().overlayLayer.appendChild(div);

  // set this as locally scoped var so event does not get confused
  var me = this;

  // Add a listener - we'll accept clicks anywhere on this div, but you may want
  // to validate the click i.e. verify it occurred in some portion of your overlay.
  google.maps.event.addDomListener(div, 'click', function() {
    google.maps.event.trigger(me, 'click');
  });

  // Position your overlay etc.
}
Virgy answered 4/8, 2010 at 3:57 Comment(3)
Sweet. Actually that recursively triggers clicks on the div so you need to trigger the second click on the overlay itself: var that = this; google.maps.event.addDomListener(this.div, 'click', function() { google.maps.event.trigger(that, 'click'); });Dynamics
Ah yes, I closure'd myself. I intended that internal this to be a reference to this in the outer scope :) ThanksVirgy
I had to combine your answer with @Tim's answer to make it work in API v3.Benison
E
2

for GoogleAPI v3. As guys said below, but with some corrections:

In LocalityCustomOverlay.prototype.onAdd function:

var self = this;
google.maps.event.addDomListener(this._div, 'click', function(event) {
    // stop click reaction on another layers
    event.stopPropagation();

    // add also event to 3rd parameter for catching
    google.maps.event.trigger(self, 'click', event); 
});

Outside, directly to your custom overlay:

google.maps.event.addListener(CUSTOM_OVERLAY_OBJECT, 'click', function(event) {
    console.log('event:', event);
});
Eleemosynary answered 18/4, 2016 at 17:20 Comment(0)
H
1

You may also want stop event propagation, so that clicks on the Overlay will not propagate to elements below (e.g. polygons, markers, etc, depends on your Pane)

//add element to clickable layer 
this.getPanes().overlayMouseTarget.appendChild(div); // or floatPane

// set this as locally scoped var so event does not get confused
var me = this;

// Add a listener - we'll accept clicks anywhere on this div, but you may want
// to validate the click i.e. verify it occurred in some portion of your overlay.
google.maps.event.addDomListener(div, 'click', function(events) {
    if (/*handling event*/) {
        event.preventDefault(); // The important part
    }
    else {
        google.maps.event.trigger(me, 'click');
    }
});
Halfassed answered 14/4, 2016 at 14:12 Comment(0)
N
0

The simple way of making your map overlay clickable is to name the Overlay in the addListener event:

 google.maps.event.addListener(historicalOverlay, 'click', function(event) {
                placeMarker(event.latLng);

It works beautifully!!!

Nevermore answered 5/3, 2024 at 11:20 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.