2013-12-13 3 views
23

Я пытаюсь отобразить «маску» на моем клиенте, в то время как файл динамически генерируется на стороне сервера. Похоже, что рекомендуется работать для этого (так как это не ajax) заключается в использовании iframe и прослушивании из события onload или done, чтобы определить, когда файл фактически отправлен клиенту с сервера.Событие «load» не запускается, когда iframe загружается в Chrome

вот мой угловой код:

var url = // url to my api 
    var e = angular.element("<iframe style='display:none' src=" + url + "></iframe>"); 
    e.load(function() { 
     $scope.$apply(function() { 
      $scope.exporting = false; // this will remove the mask/spinner 
     }); 
    }); 
    angular.element('body').append(e); 

Это отлично работает в Firefox, но не повезло в Chrome. Я также попытался использовать функцию onload:

e.onload = function() { //unmask here } 

Но мне тоже не повезло.

Идеи?

+0

Вы пытались добавить нагрузку непосредственно в html iframe? У меня были некоторые проблемы с заказом, в котором Chrome загружает элементы и связанные с ними события в прошлом. – cronoklee

+0

Yup просто попробовал. По-прежнему срабатывает FF, но не в Chrome. – lostintranslation

+0

Хмм, а как насчет URL? Вы не собираетесь перекрестный домен, не так ли? – cronoklee

ответ

15

К сожалению, невозможно использовать событие iframe onload в Chrome, если содержимое является вложением. Этот answer может предоставить вам представление о том, как вы можете обойти его.

+0

Короче говоря, обработчики событий «readystatechange» и 'onload' не вызываются для загрузки в Chrome. – rtcherry

+0

Пожалуйста, обратитесь к следующему сообщению для примера кода: stackoverflow.com/questions/12076494/.... Мне потребовалось немного времени, чтобы выяснить, что ряд других ответов в другом месте, которые относятся к использованию события onload, где фактически ложно. Возможно, это связано с тем, что последние веб-браузеры больше соответствуют спецификации. – RZet

4

Вы можете сделать это по-другому:

В основном документе:

function iframeLoaded() { 
    $scope.$apply(function() { 
      $scope.exporting = false; // this will remove the mask/spinner 
     }); 
} 

var url = // url to my api 
var e = angular.element("<iframe style='display:none' src=" + url + "></iframe>"); 
angular.element('body').append(e); 

В IFrame документе (это, внутри HTML страницы, на которую ссылается URL)

window.onload = function() { 
     parent.iframeLoaded(); 
    } 

Это будет работать, если главная страница и страница внутри iframe находятся в одном и том же доме айн.

На самом деле, вы можете получить доступ к родителю через:

window.parent 
parent 
//and, if the parent is the top-level document, and not inside another frame 
top   
window.top 

Это безопаснее использовать window.parent поскольку переменные parent и top могут быть перезаписаны (как правило, не предусматривается).

0

вы должны учитывать 2 момента:

1- Прежде всего, если ваш URL имеет другое доменное имя, это не возможно сделать это только если у вас есть доступ к другому домену, чтобы добавить заголовок Access-Control-Allow-Origin: * , чтобы исправить это, перейдите к этому link.

2-, но если он имеет тот же домен, или вы добавили Access-Control-Allow-Origin: * в заголовках вашего домена, вы можете делать то, что вы хотите, как это:

var url = // url to my api 
var e = angular.element("<iframe style='display:none' src=" + url + "></iframe>"); 
angular.element(document.body).append(e); 
e[0].contentWindow.onload = function() { 
    $scope.$apply(function() { 
     $scope.exporting = false; // this will remove the mask/spinner 
    }); 
}; 

Я сделал это во всех видах браузеров ,

0

Я только что заметил, что Chrome не всегда запускает событие загрузки для главной страницы, так что это может повлиять на iframes, поскольку они в основном обрабатываются одинаково.

Используйте инструменты Dev или Performance api, чтобы проверить, запущено ли событие загрузки.

Я только что проверил http://ee.co.uk/, и если вы откроете консоль и введите window.performance.вы найдете записи для domComplete, loadEventStart и loadEventEnd равны 0 - по крайней мере, в это текущее время :)

Похоже, что здесь проблема с Chrome - я проверил его на двух ПК с использованием последней версии 31.0.1650.63.

Обновление: снова проверяется ee и запускается событие, но не при последующих перезагрузках, поэтому это прерывисто и может быть связано с ошибками загрузки на их сайте. Но событие загрузки должно срабатывать.

Эта проблема возникла на 5 или 6 сайтах для меня сейчас в последний день, так как я заметил, что мой собственный мониторинг сайта иногда не удался. Только просто определил причину этого. Мне нужен сон красоты, тогда я буду исследовать дальше, когда буду бодрствовать.

7

Ненавижу это, но я не мог найти другого способа, кроме проверки того, по-прежнему ли он загружается или нет, за исключением проверки с интервалом.

var timer = setInterval(function() { 
    iframe = document.getElementById('iframedownload'); 
    var iframeDoc = iframe.contentDocument || iframe.contentWindow.document; 
    // Check if loading is complete 
    if (iframeDoc.readyState == 'complete' || iframeDoc.readyState == 'interactive') { 
     loadingOff(); 
     clearInterval(timer); 
     return; 
    } 
}, 4000); 
+1

Это должен быть принятый ответ для прямых загрузок. Единственная часть, которую я бы добавил, - это максимальное время, поэтому она не сидит и не ждет навсегда. – runfaj

Смежные вопросы