什么是破坏地图实例的正确方法?

Cha*_*rth 86 javascript google-maps-api-3

我最近开发了一个html5移动应用程序.该应用程序是单个页面,其中导航哈希更改事件替换整个DOM.该应用程序的一部分是使用API​​ v3的Google Map.在从DOM中删除map div之前,我想删除所有事件处理程序/侦听器并释放尽可能多的内存,因为用户可能无法再次返回该部分.

破坏地图实例的最佳方法是什么?

Sea*_*key 45

我在这个问题上添加了第二个答案,因为我不想通过对我之前的答案的后续评论来回删除.

但我最近发现了一些直接解决你的问题的信息,所以我想分享.我不知道您是否意识到这一点,但在Google Maps API办公时间2012年5月9日视频期间,Google的 Chris Broadfoot和Luke Mahe 从stackoverflow 讨论了这个问题.如果您将视频播放设置为12:50,那么这就是他们讨论您的问题的部分.

从本质上讲,他们承认这是一个错误,但也补充说他们并不真正支持涉及创建/销毁连续映射实例的用例.他们强烈建议创建一个地图实例,并在任何此类场景中重复使用它.他们还谈到将map设置为null,并明确删除事件侦听器.你表达了对事件监听器的担忧,我认为将map设置为null就足够了,但看起来你的关注是有效的,因为他们特别提到了事件监听器.他们还建议完全删除保存地图的DIV.

无论如何,只是想传递这一点,并确保它包含在stackoverflow讨论中,希望它能帮助你和其他人 -

  • 太棒了..这是2018年,似乎还没有办法做到这一点. (4认同)
  • 谢谢 - 我让他们在办公时间处理这个问题,但还没有机会查看视频. (2认同)

Cha*_*rth 26

官方的回答是你不知道.应该重用单个页面应用程序中的映射实例,而不是销毁然后重新创建.

对于某些单页面应用程序,这可能意味着重新构建解决方案,以便一旦创建了映射,它就可以隐藏或与DOM断开连接,但它永远不会被破坏/重新创建.

  • 看起来这个问题已经[从版本 3.38.1 开始修复](https://issuetracker.google.com/issues/35821412#comment65)(尽管我还没有独立验证)。 (3认同)

Pao*_*oni 12

因为显然你无法真正破坏地图实例,如果有这种方法可以减少这个问题

  • 你需要在网站上一次显示几张地图
  • 地图数量可能会随着用户互动而改变
  • 地图需要隐藏并与其他组件一起重新显示(即它们不会出现在DOM中的固定位置)

保留一组地图实例.该池保留正在使用的实例的跟踪,当它被请求一个新实例时,它检查是否有任何可用的映射实例是空闲的:如果是,它将返回一个现有实例,如果不是,它将创建一个新的地图实例并将其返回,将其添加到池中.这样,您将只有最大数量的实例等于您在屏幕上同时显示的最大地图数.我正在使用此代码(它需要jQuery):

var mapInstancesPool = {
 pool: [],
 used: 0,
 getInstance: function(options){
    if(mapInstancesPool.used >= mapInstancesPool.pool.length){
        mapInstancesPool.used++;
        mapInstancesPool.pool.push (mapInstancesPool.createNewInstance(options));
    } else { 
        mapInstancesPool.used++;
    }
    return mapInstancesPool.pool[mapInstancesPool.used-1];
 },
 reset: function(){
    mapInstancesPool.used = 0;
 },
 createNewInstance: function(options){
    var div = $("<div></div>").addClass("myDivClassHereForStyling");
    var map =   new google.maps.Map(div[0], options);
    return {
        map: map,
        div: div
    }
 }
}
Run Code Online (Sandbox Code Playgroud)

你传递起始地图选项(根据google.maps.Map的构造函数的第二个参数),它返回地图实例(你可以在其上调用与google.maps.Map相关的函数)和容器,你可以使用"myDivClassHereForStyling"类来设置样式,并且可以使用dinamically附加到DOM.如果需要重置系统,可以使用mapInstancesPool.reset().它会将计数器重置为0,同时保留池中的所有现有实例以供重用.在我的应用程序中,我需要立即删除所有地图并创建一组新的地图,因此没有回收特定地图实例的功能:您的里程可能会有所不同.要从屏幕上删除地图,我使用jQuery的分离,它不会破坏地图的容器.

通过使用这个系统,并使用

google.maps.event.clearInstanceListeners(window);
google.maps.event.clearInstanceListeners(document);
Run Code Online (Sandbox Code Playgroud)

并运行

google.maps.event.clearInstanceListeners(divReference[0]);
divReference.detach()
Run Code Online (Sandbox Code Playgroud)

(其中divReference是div的jQuery对象从实例池返回)我正在移除的每个div上,我设法保持Chrome的内存使用量或多或少稳定,而不是每次删除地图并添加新地图时都会增加.


And*_*ach 5

我建议删除map div的内容并使用delete保存对地图的引用的变量,并可能明确地显示delete任何事件侦听器.

但是,有一个公认的错误,这可能不起作用.