2017-05-23 77 views
-1

我正在從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

回答

0

答案很簡單,只需使用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); 
     });