Document.readystate说谎谷歌地图正在加载的画布图像

问题描述:

我正在从iframe中打印包含谷歌地图API v3地图的页面。我实现了下面的代码,以确保页面在打印iframe之前已经完全加载。Document.readystate说谎谷歌地图正在加载的画布图像

/** 
* Auto print the page once the full document has finished loading 
*/ 
function checkDocumentStateChange(documentElement) { 

    var document = documentElement; 
    console.log('Document ReadyState: ' + document.readyState); 
    document.onreadystatechange = function() { 

    console.log('Document ReadyState: ' + document.readyState); 

    if (document.readyState === 'complete') { 
     console.log("Document fully loaded!"); 
     console.log("Printing report from within iframe"); 
     setTimeout(function() { 
      window.print(); 

      var requestOrigin = '@viewModel.RequestOrigin'; 
      if(!!requestOrigin) { 
       // Tell the parent window that the print has occurred, so it can prepare to cleanup and remove this iframe 
       console.log("Send postMessage: secret"); 
       parent.postMessage('secret', requestOrigin); 
      } 
     }, 500); 

    } 
    } 

}

然而,即使与500毫秒的延迟之后document.readystate === 'complete'是真实的,很多时候,页面打印带有灰色/空白的谷歌地图的画布,没有图像。

如果我再次打开window.print()而不重新加载页面,则会按预期方式打印带有所有地图图像的iframe。因此,文档就绪状态在说谎。

我能做些什么来解决这个问题,除了增加延迟甚至更长的时间(我不想这样做,因为它惩罚的人等待时长快速加载内容时)

+3

gmaps补充内容,该内容加载不影响readyState的 – dandavis

+0

如果你控制的iframe,可以在其上设置一个CORS头。 –

+0

@dandavis多数民众赞成在我的想法。 – TetraDev

答案很简单,只需使用Google Maps事件处理程序api。在我的测试中,按顺序触发bounds_changed,然后tilesloaded,最后idle。所以我只是设置了一个标志,以便稍后检查idle事件,并且它完美地工作。后该文件已准备就绪

 // this callback runs when the mapobject is created and rendered (because bound_changed fires at initialization), only fire it once to prevent unnecessary callbacks during panning/zooming 
     google.maps.event.addListenerOnce(map, 'bounds_changed', function() { 
     // do something only the first time the map is loaded 
     console.log("Google Maps event: bounds_changed"); 
     }); 

     // this callback runs when the mapobject is shown for the first time and all tiles are loaded 
     google.maps.event.addListener(map, 'tilesloaded', function() { 
     console.log("Google Maps event: tilesloaded"); 
     }); 

     // this callback runs when the mapobject is fully created and rendered and the map is completely idle 
     google.maps.event.addListener(map, 'idle', function() { 
     // do something only the first time the map is loaded 
     console.log("Google Maps event: idle"); 
     mapReadyToPrint = true; 
     console.log("mapReadyToPrint:", mapReadyToPrint); 
     });