谷歌地图infobubble动态内容不会在第一次单击标记时加载 [英] google maps infobubble dynamic content not loading on first marker click

查看:160
本文介绍了谷歌地图infobubble动态内容不会在第一次单击标记时加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在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 work

  • added 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆