谷歌地图infobubble动态内容不会在第一次单击标记时加载 [英] google maps infobubble dynamic content not loading on first marker click
问题描述
我正在尝试在Google地图 infobubble 中添加动态内容:
-第一次单击标记,将显示一个空的信息气泡
-在 SECOND 上单击标记,正确的内容已加载
按照此答案,我正在使用先前定义的信息气泡对象上的domready
事件来启动加载的函数动态内容.
...虽然该答案中的JS小提琴具有误导性,因为动态"内容实际上是在domready
之前使用new InfoBubble()
调用的content
选项加载的
我在控制台中收到所有正确的信号,表明domready
功能已完成,并且在第一次单击标记时就可以正确找到其内容.
尝试:
-
通过
信息气泡.js代码,然后将console.logs放在第1231行的任意一侧:
google.maps.event.trigger(this, 'domready');
结果表明domready实际上是在动态函数开始之前触发的. -
使用infobubble
disableAnimation: true
选项禁用动画-认为调用domready后可能会减慢infobubble的加载-但这没用 -
增加了
setTimeout()
长达3秒的时间,但这似乎无济于事...不管怎么说,这都是一个糟糕的技巧.
如何在第一次单击标记时获取要加载的动态内容?
JS小提琴在这里
注意:
-对于js小提琴示例,我正在使用$.get()
调用-因为在我的应用程序中,我正在使用小胡子将模板加载到infobubble
-所加载的示例内容与$.get()
调用无关(是的,没有$.get()
调用我可以实现相同的功能),但是我只是想对自己的应用程序使用类似的代码布局+计时>
感谢您的观察 我已经找到了解决方案-确实与domready
事件触发器在 infobubble.js 代码.
不幸的是,它当前位于updateContent_()
函数中,该函数由open_()
调用,在调用setMap()
之前-这意味着在将infoBubble添加到DOM之前会触发domready
.
不可能在open_()
函数中的setMap()
调用之后简单地添加domready
触发器,因为setMap()
是异步的...并且setMap()
函数没有特定的回调. /p>
但是,根据 OverlayView的文档(此插件正在使用的)setMap()
函数在使用有效的地图对象调用setMap()
之后调用onAdd()
函数:
onAdd():实现此方法以初始化叠加层DOM元素.在使用有效的映射调用setMap()之后,将调用此方法一次.此时,窗格和投影将已初始化.
更简单地:
在onAdd()方法中,您应该创建DOM对象并将其作为窗格的子代附加.
因此,我们应该在onAdd()
函数内触发domready
事件,在之后将infoBubble
附加到地图窗格:
/**
* On Adding the InfoBubble to a map
* Implementing the OverlayView interface
*/
InfoBubble.prototype.onAdd = function() {
if (!this.bubble_) {
this.buildDom_();
}
this.addEvents_();
var panes = this.getPanes();
if (panes) {
panes.floatPane.appendChild(this.bubble_);
panes.floatShadow.appendChild(this.bubbleShadow_);
}
google.maps.event.trigger(this, 'domready'); // infobubble has now been added to DOM so we can fire `domready`
};
我为Google创建了拉动请求更新 infobubble.js代码并解决此问题.
JS Fiddle在此处提供了更新的代码(有关新的domready
位置,请参见javascript窗口中的第910行)
http://jsfiddle.net/goredwards/7r96we66/ >
注意:
-我在jsfiddle中的旧domready
调用和正确的(更新的)domready
调用中添加了时间戳-您将在console.log
中看到它们-在我的系统上大约需要20毫秒(这会有所不同(系统速度)
-它表明旧的domready确实在将infoBubble
附加到窗格之前触发了
-给出了domready
调用
setTimeout
的想法
如果您想使用没有修复的原始代码-和setTimeout
hack: http://jsfiddle.net/goredwards/xeL7dxye/
...您可以按setTimeout
持续时间进行操作,看看最小值是多少-我在快速的计算机上降至5ms左右.显然,您必须在此代码中采用 other 的方式来处理最慢的机器(即,将setTimeout
持续时间设置为可以承受的最大水平-无需烦恼) 〜150-250ms-甚至覆盖了最慢的系统.
...,或者您可以复制并更新 infobubble.js 代码并完成它.
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 by open_()
, before setMap()
is called - which means that domready
is fired BEFORE the infoBubble is added to the DOM.
It's not possible to simply add the domready
trigger after the setMap()
call in the open_()
function because setMap()
is asynchronous... and the setMap()
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 the onAdd()
function once AFTER setMap()
is called with a valid map object:
onAdd(): Implement this method to initialize the overlay DOM elements. This method is called once after setMap() is called with a valid map. At this point, panes and projection will have been initialized.
and more simply:
In the onAdd() method, you should create DOM objects and append them as children of the panes.
Therefore we should fire the domready
event within the onAdd()
function, after the infoBubble
is appended to the map panes:
/**
* On Adding the InfoBubble to a map
* Implementing the OverlayView interface
*/
InfoBubble.prototype.onAdd = function() {
if (!this.bubble_) {
this.buildDom_();
}
this.addEvents_();
var panes = this.getPanes();
if (panes) {
panes.floatPane.appendChild(this.bubble_);
panes.floatShadow.appendChild(this.bubbleShadow_);
}
google.maps.event.trigger(this, 'domready'); // infobubble has now been added to DOM so we can fire `domready`
};
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 the console.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 a domready
call
If 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 the setTimeout
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.
这篇关于谷歌地图infobubble动态内容不会在第一次单击标记时加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!