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 a
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.
OverlayView
class.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
You might want to check google.maps.InfoWindow
(https://developers.google.com/maps/documentation/javascript/overlays#InfoWindows) and the google.maps.Marker
(https://developers.google.com/maps/documentation/javascript/reference#Marker) of google maps. Any CSS you apply on the page will be applied to the InfoWindow as well.