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!
You might want to check
google.maps.InfoWindow
(https://developers.google.com/maps/documentation/javascript/overlays#InfoWindows) and thegoogle.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.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 extendsMVCObject
. TheOverlayView
class also extendsMVCObject
. To make your HTML/CSS implemented customized marker behave normally and resemble onegoogle.maps.Marker
at behavioral and event-communication level (but not visual level), extendingOverlayView
class is one safe way, since constructing one instance ofOverlayView
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 overridingdraw()
is that, this method is intrinsically bound to several google map events, such aszoom_changed
. The purpose ofdraw()
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, onegoogle.maps.Marker
redraws itself every time when user zoom in or zoom out the map. Additionally, there are many different situations that will triggerdraw()
Similarly,onAdd()
is invoked when tiles of map are ready,onRemove()
is invoked whensetMap()
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 classOverlayView
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 extendingOverlayView
. 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
andtop
, andwidth
is determined by pre-definedgoogle.maps.Bounds
, you should change this. You need code like following: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 likeonclick
, 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 ofmouseover
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