I'm trying to add dynamic content inside a google maps infobubble:
- one first marker click an empty infobubble appears
- on SECOND click of the marker the correct content is loaded
As per this answer I'm using the domready
event on the previously defined infobubble object to launch the function that loads the dynamic content.
...although the JS fiddle in that answer is misleading since the 'dynamic' content is actually loaded prior to domready
using the content
option of the new InfoBubble()
call
I'm getting all the right signals in console that the domready
function is being completed and the content is being correctly found on 1st marker click.
Tried:
looked through the infobubble.js code and put console.logs either side of line 1231:
google.maps.event.trigger(this, 'domready');
The results show that domready is indeed being fired PRIOR to the start of the dynamic function.disabling animation using the infobubble
disableAnimation: true
option - thinking that could be slowing the infobubble load after domready is called - but it didn't workadded
setTimeout()
of up to 3 seconds but that doesn't seem to help... and that would be a poor hack anyway.
How can I get the dynamic content to load on first click of the marker ?
JS Fiddle here
Notes:
- for the js fiddle example I'm using a $.get()
call - since in my application I'm using moustache to load a template into the infobubble
- the example content being loaded has nothing to do with the $.get()
call (and yes I could achieve the same without the $.get()
call) but I'm just trying to use similar code layout + timing to my own application
Thanks to the observations in the answer by Dr.Molle I've figured out the solution - which is indeed related to the placement of the
domready
event trigger in the infobubble.js code.Unfortunately it's currently located in the
updateContent_()
function, which is called byopen_()
, beforesetMap()
is called - which means thatdomready
is fired BEFORE the infoBubble is added to the DOM.It's not possible to simply add the
domready
trigger after thesetMap()
call in theopen_()
function becausesetMap()
is asynchronous... and thesetMap()
function doesn't have a specific callback.However, according to the documentation for OverlayView (which is what is being used by this plugin) the
setMap()
function calls theonAdd()
function once AFTERsetMap()
is called with a valid map object:and more simply:
Therefore we should fire the
domready
event within theonAdd()
function, after theinfoBubble
is appended to the map panes:I've created a pull-request for google to update the infobubble.js code and fix this issue.
JS Fiddle here with updated code (see line 910 in the javascript window for new
domready
placement)http://jsfiddle.net/goredwards/7r96we66/
Notes:
- I've added timestamps in the jsfiddle at the old
domready
call and the correct (updated)domready
call - you'll see them in theconsole.log
- it comes to about 20ms on my system (it will vary with system speed)- it shows that the old domready was indeed firing prior to the
infoBubble
being appended to the panes- this gives an idea of the minimum
setTimeout
you'd need to put around any functions within adomready
callIf you want to use the original code without the fix - and a
setTimeout
hack: http://jsfiddle.net/goredwards/xeL7dxye/...you can play around with the
setTimeout
duration and see what the minimum is - I got down to around 5ms on a fast machine. Obviously you'd have to go the other way in production code with this hack to cope with the slowest machines (ie you'd put thesetTimeout
duration at the maximum level you can stand - without annoyance ~150-250ms - to cover even your slowest systems).... or you could just copy and update the infobubble.js code and be done with it.
the issue seems to be the
open_
-method of the infobubble(which will be called in theopen
-method):It first calls the method
updateContent_
(where thedomready
-event will be triggered) and then sets themap
. But the overlay will not be added to the map until themap
-property has been set, the content is a DocumentFragment/Node that hasn't been attached to the document yet, so jQuery may not find it.Possible solution:
Use the
content_
-property of the infobubble as context for the jQuery-selector, then it shouldn't matter if the content already has been attached to the documenthttp://jsfiddle.net/doktormolle/aLtz76ym/