2009-10-06 15 views
10

Załóżmy, że mamy następujący plik HTML:Jak wyzwalać zdarzenie onload podczas pobierania pliku w elemencie iframe?

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>Test iframe download</title> 
<script type="text/javascript"> 

var init = 0; 

function download() { 
    document.getElementById("dload_frame").src = "http://example.com/dload.py"; 
} 

function alert() { 
    if (init == 0) { 
    init = 1; 
    } 
    else { 
    document.getElementById("alert_span").innerHTML = "Got it!"; 
    } 
} 

</script> 
</head> 
<body> 

    <span id="alert_span">Main content.</span><br/> 
    <input type="button" value="Download" id="btn" onclick="download()" /> 
    <iframe id="dload_frame" src="http://404.com/404" onload="alert()"> </iframe> 

</body> 
</html> 

Teraz, jeśli adres URL, do którego iframe src jest przepisany do (w tym przypadku - „http://example.com/dload.py”) zwraca HTML, nie ma problemu: Zdarzenie onload, zawartość przęsła zostaje zastąpiona, wszyscy są szczęśliwi.

Jednakże, jeśli typ zawartości pliku zwróconym przez URL jest ustawiony na coś, co zmusza przeglądarkę, aby otworzyć okno dialogowe Zapisz plik, onload wydarzenie iframe nigdy nie odpala.

Czy istnieje sposób obejścia tego problemu? Korzystanie z elementów iframe nie jest konieczne, więc pożądanym zachowaniem jest uruchomienie wywołania zwrotnego po tym, jak przeglądarka rozpocznie pobieranie dostarczonego pliku.

+0

Możesz spróbować pobrać plik za pomocą ajax, a następnie utworzyć tag (link) 'a' z identyfikatorem URI danych i kliknąć na nim, ale nie przetestowałem go z dużymi plikami. – jcubic

Odpowiedz

1

jakie napotkał ten sam problem jak ten: Oto mój obejście, należy sprawdzić, czy to działa na ty:

<script> 
function download(){ 
    var url = 'http://example.com/dload.py'; 
    var htm = '<iframe src="' + url +'" onload="downloadComplete()"></iframe>'; 
    document.getElementById('frameDiv').innerHTML = htm; 
} 
</script> 

<div style="display:none" id="frameDiv"> 
</div> 
<button onclick="download()">download file</button> 

O ile pamiętam, zdarzenie onrame zdarzenia iframe jest uruchamiane tylko raz. Ustawienie innej wartości dla atrybutu src nie spowoduje ponownego uruchomienia zdarzenia onload.

+0

Bardzo sprytny! Dziękuję Ci. To nie działa w Chrome, ale przynajmniej w Firefoksie to działa i działa wiele razy, ponieważ za każdym razem jest to faktycznie nowa iframe że odpala zdarzenie onload, ponieważ zastąpić innerHTML. – dpq

+0

Cieszę się, że to zadziałało, jednak nie testowałem tego w Chrome. – jerjer

+0

Wygląda na to, że działa w podobnym problemie, który miałem - tak długo, jak działa Firebug. Kiedy wypróbowałem w Firefoksie 2 lub 3 bez Firebug, nagłe ładowanie się nie uruchomiło.Czy ktoś wie, gdzie jest różnica? – justkt

-1

Może potrzebujesz pomocy jQuery za to, na przykład, można to zrobić:

$.get('http://example.com/dload.py',{},function(result){ 
    $('alert_span').html(result);//or some content 
}); 
+3

Nie, to nie zadziała. Wywołanie asynchroniczne zapisze zwróconą wartość w zmiennej wynikowej i przekaże ją do funkcji wywołania zwrotnego zamiast otwierania okna dialogowego zapisu. – dpq

0

Mam ten sam problem, onLoad obsługi jest tylko ogień, gdy zmiana treści. Jeśli pobierzesz plik. Jeśli usuniesz nagłówek HTTP, aby wydrukować zawartość pliku na elemencie iframe, to onload jest poprawnie uruchamiany.

+1

Jak mogę usunąć nagłówki HTTP i móc pobrać plik w przeglądarce internetowej? – anmarti

1

Moje rozwiązanie po wielu różnych podejść, aby dostać tę pracę całej ff czyli Safari i Chrome nie posiada 2 stopniową pobieranie.

Oryginalne żądanie JS do utworzenia elementu iframe wczytuje src, który normalnie załadowałby pdf Jednak src ładuje teraz stronę z jeszcze innym elementem iframe, który zawiera teraz URL pliku pdf. w odpowiedzi html I wyzwolić onload a także catchall setTimeout funciton który wywołuje moją odpowiedź na window.parent.window.handlerfunction które mój onload na najwyższym iframe byłby. Rezultatem jest do pobrania w formacie PDF i spust na najwyższym poziomie rodzica funkcji obsługi, która działa na przeglądarkach, ponieważ nie opiera się na wykryciu rzeczywistego obciążenia iframe ale raczej opiera się na obsługiwanych rodzic/dziecko relacje okiennych.

nadzieję, że to pomoże ktoś, kto był również zatrzymany

0

Można sprawdzić właściwość iframe readyState wielokrotnie po krótkim odstępach czasu, aż zostanie zakończona.

function iframe_onload(iframe_id, js) { 
    var iframe = document.getElementById(iframe_id); 
    var iframeDoc = iframe.contentDocument || iframe.contentWindow.document; 

    if (iframeDoc.readyState == 'complete') { 
     eval(js) 
     return; 
    } 

    window.setTimeout('iframe_onload("' + iframe_id + '",`' + js + '`);', 100); 
} 
+0

Mam pobieranie bazy php i po pierwszym przepłukaniu dane są wysyłane do przeglądarki, a stan jest oznaczony jako kompletny, nawet jeśli pobieranie jest nadal w toku. – jcubic

Powiązane problemy