HTML/CSS Markers using Google Maps Javascript API v3
google-maps, html, jquery
Solution
To save readers' time, I provide demo-purpose website here
For this question. Basically, to add HTML/CSS customized markers, I suggest implementing one subclass of `OverlayView` with the help of some external library.
- First I need to clarify why you should inherit `OverlayView` class.
- Second I need to demonstrate why an external library might help.
Okay. First, The `google.maps.Marker` class extends `MVCObject`. The `OverlayView` class also extends `MVCObject`. To make your HTML/CSS implemented customized marker behave normally and resemble one `google.maps.Marker`at behavioral and event-communication level (but not visual level), extending `OverlayView` class is one safe way, since constructing one instance of `OverlayView` will somehow "register" the instance itself to the internal map events management. I will explain how this "registration" happened below.
In order to extend `OverlayView`, you need to override three methods, `onRemove()` `onAdd()`, `draw()`. The purpose of overriding `draw()` is that, this method is intrinsically bound to several google map events, such as `zoom_changed`. The purpose of `draw()` is to redraw the dom element, make it appear at right position of map canvas, and have it correctly sized on map canvas. For example, one `google.maps.Marker` redraws itself every time when user zoom in or zoom out the map. Additionally, there are many different situations that will trigger `draw()` Similarly, `onAdd()` is invoked when tiles of map are ready, `onRemove()` is invoked when `setMap()` is invoked. There is a series of events being listened by these three methods. This is how "registration" happens in my point. This also explains why extending class `OverlayView` is one safe way to implement your HTML/CSS customized marker. Because you do not need to deal with map events listening yourself when you extending `OverlayView`. Otherwise, you have to.
Specifically to this question, "to implement one custom maker", you need to do things described above also.
On the "custom OverlayView example" given in your question. I can tell you what you need to change to make it behave like one marker.
In that example. the css `left` and `top`, and `width` is determined by pre-defined `google.maps.Bounds`, you should change this. You need code like following:
CustomMarker.prototype.draw = function(){
var overlayProjection = this.getProjection();
// console.log("draw" + this.latLng);
var anchor = overlayProjection.fromLatLngToDivPixel(this.latLng);
if (this.dom_) {
this.dom_.style.top = (Math.round(anchor.y- this.height_)).toString()+'px';
this.dom_.style.left = Math.round( anchor.x - this.width_ / 2).toString() + 'px';
$(this.dom_).outerWidth(this.width_); // I need to have this jQuery method
}
// generally, the dom node left-top corner should not be generated at clicking poistion, but with offsets of both left and top
};
Also you need to handle so called "dom events" by `addDomListener()` method provided by google maps API. Why they are "so-called" events?
Because, to make the HTML nodes attached to marker instances of the extended "OverlayView" class be able to respond to user behaviors (I am not calling browser events here) like "clicking" "double clicking", developer should append the nodes to pane `overlayMouseTarget".
The reason is that, actually above `overlayMousetarget` pane, there are several other non-zero width none-zero height map HTML nodes, which "shadowed" our custom marker node added to the DOM tree. So our marker CANNOT directly receive browser events like `onclick`, even if you have implemented the DOM event handler functions for it. They are "deaf".
So the purpose of appending our customized Marker to `overlayMouseTarget` pane(node) is that, Google Maps has its own mechanism for how to process received outmost browser events. Google map process them, and then notify those nodes appended to google map mangaged panes(those five nodes: `floatPane` `mapPane` `markerLayer` `overlayLayer` `overlayMouseTarget`)
Now you can understand why I am calling the "so-called" events when you invoking "addDomListener()". Because the original "click" browser event never reached our poor markers, instead, it responds to "click" action by listening to one internal google map event which is trigger by outmost original "click" browser event.
Now, lets focus one the second point: "I need to demonstrate why an external library might help" You have to handle different google map dom listeners to complete tasks originally you can do with several lines of CSS code.
For example, to realize pseudo class `hover`, you need to implement handler of `mouseover` `mouseout` and so on, do some CSS classes adding and removal.
With external library such mapcover.js, you can just `set("mouseover": function cb() { /*your implementations here*/})`.
Have written so much, I will just show one demo here: http://easysublease.org/mapcoverjs/
The detailed implementations how you can create your HTML markers can be found here
Problem
Our company just moved from Leaflet.js to the Google Maps API; I've search high and low trying to find a simple way of integrating HTML/CSS Markers/Boxes as overlays into the Google Maps Javascript API v3. So far, i've found this tutorial: https://developers.google.com/maps/documentation/javascript/overlays#CustomOverlays Nevertheless, I find it extremely clunky and I haven't been able to inject HTML/CSS code successfully into the map. Does anybody know of an easier way of adding HTML/CSS Markers/Boxes unto Google Map? I could go ahead and hack the map by assigning top/left coordinates to divisions and then attach them to the map with jQuery to markers on google map, but this is a workaround/hack and there must be a simple way of integrating these. Thanks in advance!