0

我正在尝试在 google maps infobubble中添加动态内容:
-第一个标记单击一个空的 infobubble 出现
-在第二次单击标记时加载正确的内容

根据这个答案,我正在使用domready先前定义的 infobubble 对象上的事件来启动加载动态内容的函数。
...尽管该答案中的 JS 小提琴具有误导性,因为“动态”内容实际上是在domready使用调用content选项之前加载的new InfoBubble()

我在控制台中收到了所有正确的信号,表明该domready功能正在完成,并且在第一次标记点击时正确找到了内容。

试过:

  • 查看infobubble.js 代码并将 console.logs 放在第 1231 行的任一侧:
    google.maps.event.trigger(this, 'domready');
    结果表明 domready 确实在动态函数开始之前被触发。

  • 使用 infobubbledisableAnimation: true选项禁用动画 - 认为在调用 domready 后可能会减慢 infobubble 加载 - 但它没有用

  • 最多增加setTimeout()3 秒,但这似乎无济于事……无论如何,这将是一个糟糕的 hack。

如何在第一次单击标记时加载动态内容?

JS小提琴在这里

注意:
- 对于 js fiddle 示例,我正在使用$.get()调用 - 因为在我的应用程序中,我使用 mustache 将模板加载到 infobubble
- 正在加载的示例内容与调用无关$.get()(是的,我可以实现没有$.get()电话也一样)但我只是想对我自己的应用程序使用类似的代码布局+时间

4

2 回答 2

2

问题似乎是open_infobubble 的 -method(将在open-method 中调用):

InfoBubble.prototype.open_ = function(opt_map, opt_anchor) {
  this.updateContent_();

  if (opt_map) {
    this.setMap(opt_map);
  }
  //............................
}

它首先调用方法updateContent_domready将触发 -event),然后设置map. 但是在设置了-property之前覆盖不会添加到地图中map,内容是尚未附加到文档的DocumentFragment/Node,因此jQuery可能找不到它。

可能的解决方案:

使用content_infobubble 的 -property 作为 jQuery-selector 的上下文,那么内容是否已经附加到文档应该无关紧要

google.maps.event.addListener(marker, 'click', function () {

  google.maps.event.addListenerOnce(infoBubble,'domready',function () {

    var that=this;            
    //when we load the additional content asynchronously, 
    //make sure that it's the correct content we are loading
    var token=new Date().getTime()*Math.random();
    that.set('token',token);

    $.get('https://lh4.googleusercontent.com/-_Cox6aEnSkU/UQ_B0LK4khI/AAAAAAAAAzw/4H4dsWGPgeE/s150/go-button.png', function (myImage) {
      if(that.get('token')===token){
        $(".dialog",that.content_).html('<img id="theImg" src="https://goo.gl/phmzis" />');
      }     
        })

  });
  infoBubble.open(map, marker);
});

http://jsfiddle.net/doktormolle/aLtz76ym/

于 2015-10-17T10:37:01.647 回答
0

感谢Dr.Molle 在回答中的观察,我找到了解决方案——这确实与infobubble.js代码中domready事件触发器的位置有关。

不幸的是,它当前位于updateContent_()由 调用的函数中,open_()在调用之前setMap()- 这意味着domready在将 infoBubble 添加到 DOM 之前触发。

不可能在函数调用domready之后简单地添加触发器,因为它是异步的......并且函数没有特定的回调。setMap()open_()setMap()setMap()

但是,根据OverlayView 的文档(这是该插件所使用的),一旦使用有效的地图对象调用AFTER ,该函数就会setMap()调用该函数:onAdd()setMap()

onAdd():实现这个方法来初始化覆盖的 DOM 元素。此方法在使用有效地图调用 setMap() 后调用一次。此时,窗格和投影将已初始化。

更简单地说:

在 onAdd() 方法中,您应该创建 DOM 对象并将它们附加为窗格的子项。

因此,我们应该在函数中触发domready事件,附加到地图窗格之后:onAdd()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`
};

我为谷歌创建了一个拉取请求来更新infobubble.js 代码并解决这个问题。

JS Fiddle 更新代码(请参阅 javascript 窗口中的第 910 行以获取新domready位置)
http://jsfiddle.net/goredwards/7r96we66/

注意:
-我在旧domready调用和正确(更新)domready调用的 jsfiddle 中添加了时间戳-您会在其中看到它们console.log-在我的系统上大约需要 20 毫秒(它将随系统速度而变化)
-它显示旧的 domready 确实在infoBubble被附加到窗格之前触发
- 这给出了setTimeout您需要在domready调用 中放置任何函数的最小值

如果你想在没有修复的情况下使用原始代码 - 和一个setTimeout黑客:http: //jsfiddle.net/goredwards/xeL7dxye/
...你可以玩弄setTimeout持续时间,看看最小值是多少 - 我开始了快速机器上的 5 毫秒。显然,您必须在生产代码中使用此 hack 以应对最慢的机器(您将setTimeout持续时间设置在您可以忍受的最大水平 - 没有烦恼〜 150-250 毫秒 - 以覆盖最慢的机器)系统)。
...或者您可以复制并更新infobubble.js代码并完成它。

于 2015-10-26T22:14:12.123 回答