Document.readystate лжет о загружаемых изображениях холста Google Maps

Я печатаю страницу, содержащую карту Google Maps API v3 из iframe. Я реализовал следующий код, чтобы убедиться, что страница полностью загрузилась перед печатью iframe.

/**
*    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 миллисекунд AFTER document.readystate === 'complete' верно, часто страница печатается с серым / пустым холстом Google Maps без изображений.

Если я снова нажму window.print (), не перезагружая страницу, он распечатает iframe со всеми изображениями карты, как и ожидалось. Значит, состояние готовности документа лжет.

Что я могу сделать, чтобы решить эту проблему, кроме увеличения задержки еще больше (чего я не хочу делать, так как это наказывает людей долго ждать, когда контент загружается быстро)


person TetraDev    schedule 23.05.2017    source источник
comment
gmaps добавляет содержимое после того, как документ готов, загрузка содержимого не влияет на readyState   -  person dandavis    schedule 24.05.2017
comment
Если вы управляете iframe, вы можете установить для него заголовок CORS.   -  person Daniel Beck    schedule 24.05.2017
comment
@dandavis вот что я подумал.   -  person TetraDev    schedule 24.05.2017
comment
@daniel beck Я посмотрю на это и посмотрю, смогу ли я использовать какие-нибудь ответы. Я контролирую iframe. Я использую .postmessage для связи в домене. Чем может помочь заголовок cors в этой ситуации?   -  person TetraDev    schedule 24.05.2017
comment
Если вы уже используете postMessage, значит, у вас уже настроен CORS (иначе ваши iframe находятся в том же домене). В любом случае - вы можете использовать postMessage для отправки уведомления о срабатывании события Google Maps.   -  person Daniel Beck    schedule 24.05.2017
comment
Спасибо, с помощью другого вопроса у меня все заработало. Это помогло мне google.maps.event.addListener(map, 'idle', function () { //set flag to check for here });   -  person TetraDev    schedule 24.05.2017


Ответы (1)


Ответ был прост: просто используйте API обработчика событий Google Maps. В моих тестах он срабатывает 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);
      });
person TetraDev    schedule 24.05.2017