fredrik
fredrik

Reputation: 17617

Get DOM Element of a marker in Google Maps API 3

I'm trying to find a way to get the DOM element of a marker. It seems that Google uses different elements for showing a marker and one of handling the event.

I've figured out 2 things so far. There's a generated variable called fb that holds the DOM element on a marker object, but I think the next time Google updates the API, it will be named something different. So no go.

Second, if one attach a click event to a marker the API send the event DOM element as arguments to what ever function you have specified. While looking through it in Firebug I can't find any relations between the two.

What I'm trying to accomplish is to manipulate the DOM element() and feed it more information then just a 'div' element with a background.

I've done this in version 2 using a name property(undocumented) that generates an id on the div element.

Does anyone have an idea?

Upvotes: 25

Views: 24509

Answers (5)

Mehyar Sawas
Mehyar Sawas

Reputation: 1266

I have checked that google maps marker click event has a MosueEvent property in it and the target of the mouse event is the dom element of the marker.

It worked for me until i found out that the property name has changed from tb to rb. I did not know why and I could not find an explaination for that in the google maps api docs but I have created a work around.

I check the click event object properties for the one which is an instance of MouseEvent and I use its target as the marker dom element.

marker.addListener('click', (e) => {

      let markerElement;

   // with underscore
    _.toArray(markerClickEvent).some(item => {
        if (item instanceof MouseEvent) {
            markerElement = item.target;
            return true;
        }
    });
  // or maybe with for loop
for (let key in markerClickEvent) {
        if (markerClickEvent.hasOwnProperty(key) && markerClickEvent[key] instanceof MouseEvent) {
            markerElement = markerClickEvent[key].target;
            break;
        }
    }
});

Upvotes: 1

Matt
Matt

Reputation: 51

I was looking for the DOM element too in order to implement a custom tooltip. After a while digging into google overlays, custom libraries and so on, i've ended up with the following solution based on fredrik's title approach (using jQuery) :

google.maps.event.addListener(marker, 'mouseover', function() {

    if (!this.hovercardInitialized) {

        var markerInDOM = $('div[title="' + this.title + '"]').get(0);

        // do whatever you want with the DOM element

        this.hovercardInitialized = true;
    }

});

Hope this helps someone.

Upvotes: 5

BenjyCook
BenjyCook

Reputation: 381

I've found this method to be useful, although it might not be suitable for all environments. When setting the marker image, add a unique anchor to the URL. For example:

// Create the icon
var icon = new google.maps.MarkerImage(
    "data/ui/marker.png",
    new google.maps.Size(64, 64),
    new google.maps.Point(0,0),
    new google.maps.Point(48, 32)
);

// Determine a unique id somehow, perhaps from your data
var markerId = Math.floor(Math.random() * 1000000);
icon.url += "#" + markerId;

// Set up options for the marker
var marker = new google.maps.Marker({
    map: map,
    optimized: false,
    icon: icon,
    id: markerId,
    uniqueSrc: icon.url
});

Now you have a unique selector i.e.:

$("img[src='data/ui/marker.png#619299']")

or if you have the marker:

$("img[src='" + marker.uniqueSrc + "']")

Upvotes: 19

user2806330
user2806330

Reputation: 21

  1. Customize overlays (by implements onAdd, draw, remove) while drag it has some issues.
  2. Maybe you can get the marker dom element by the class name gmnoprint and the index it has been appended in.

Upvotes: 2

fredrik
fredrik

Reputation: 17617

I found a really really bad workaround. One can use the title attribute to pass a id property.

fixMarkerId = function () {
                $('div[title^="mtg_"]').each(function (index, elem) {
                    el = $(elem);
                    el.attr('id', el.attr('title'));
                    el.removeAttr('title');
                });
            },
            tryAgainFixMarkerId = function () {
                if ($('div[title^="mtg_"]').length) {
                    fixMarkerId();
                } else {
                    setTimeout(function () {
                        tryAgainFixMarkerId();
                    }, 100);
                };
            }

if ($('div[title^="mtg_"]').length) {
                fixMarkerId();
            } else {
                setTimeout(function () {
                    tryAgainFixMarkerId();
                }, 100);
            };

I would strongly not recommend this solution for any production environment. But for now I use it so that I can keep developing. But still looking for a better solution.

Upvotes: 4

Related Questions