Określanie zawartości elementu iframe zamiast atrybutu src na stronie


88

Obecnie pracuję nad formularzem, który zawiera dane wejściowe do plików do przesyłania zdjęć. onchange()Dla tych danych wejściowych istnieje zdarzenie, które przesyła obrazy do pliku iframe, a następnie dynamicznie ładuje przesłane obrazy do formularza, z polami, które mają być dla nich zmodyfikowane (takie jak nazwa i lokalizacja geograficzna ).

Ponieważ nie mogę zagnieżdżać form, file_inputplik jest również zawarty w pliku iframe. W końcu używam iframewnętrza innego iframe. Więc mam coś takiego:

<form>
<!-- LOTS OF FIELDS!! -->
<iframe src="file_input_url">
<!-- iframe which loads a page of a form with a file input-->
</iframe>
</form>

HTML i ładowane do iframejest coś takiego (z wyłączeniem html, heada bodytagi)

<form target="upload_iframe">
<input type="file" onchange="this.form.submit()">
</form>
<iframe name="upload_iframe"></iframe>

Działa to świetnie, z wyjątkiem faktu, że załadowanie pierwszego zajmuje kilka sekund iframe, więc plik wejściowy nie ładuje się wraz z resztą strony. Nie jest to wizualnie idealne. Mógłbym to rozwiązać, gdybym mógł określić iframetreść bez konieczności ładowania innej strony (określonej przez file_input_urlw pierwszej iframe).

Czy istnieje sposób określenia iframetreści w tym samym dokumencie, czy też można ją określić tylko za pomocą srcatrybutu, co wymaga załadowania innej strony?


Załadowanie tego elementu iframe nie powinno zająć „kilku sekund”. Spodziewałbym się, że będzie to raczej jedna dziesiąta milisekundy plus „czas na ugryzienie” (który również powinien wynosić milisekundy). Powinieneś zbadać, co powoduje całe opóźnienie - prawdopodobnie coś jest nie tak z twoim serwerem.
Abhi Beckert

Odpowiedzi:


95

Możesz .write()zawartość w dokumencie iframe. Przykład:

<iframe id="FileFrame" src="about:blank"></iframe>

<script type="text/javascript">
   var doc = document.getElementById('FileFrame').contentWindow.document;
   doc.open();
   doc.write('<html><head><title></title></head><body>Hello world.</body></html>');
   doc.close();
</script>

1
Myślałem jednak o takiej możliwości, jednak kod HTML, który należy załadować do elementu iframe, jest złożony, a obsługa go w całości w javascript w celu zapisania go w ramce iframe zbytnio utrudniłby implementację (do tego stopnia, że ​​wolę Zostaw to tak, jak jest).
orlox

2
@orlox: Pobierz zawartość z serwera za pomocą Ajax i wstrzyknij ją. Jeśli nie chcesz iść w ten sposób, utwórz ukryty divelement z zawartością i umieść jego zawartość iframepomiędzy <body>i </body>.
stackular

11
Im więcej dowiaduję się o ograniczeniach iframe, tym bardziej ich nienawidzę
John Magnolia

1
Jak uniknąć pojedynczych cudzysłowów za pomocą tej metody? Niektóre z nich są ważne dla HTML (np. Class = 'example'), niektóre są ważne dla CSS (np. Font-family: 'Verdana';), a niektóre zawierają treść (np. George O'Malley).
Dan Bechard

2
@Dan: Aby uciec przed jakąkolwiek wartością, która ma być użyta w ciągu JavaScript rozdzielanym apostrofami, należy najpierw zmienić znaczenie ukośników odwrotnych, a następnie apostrofów. Na przykład przy użyciu C #, aby wstawić ciąg znaków w kodzie: doc.write('<%= html.Replace("\\", "\\\\").Replace("'", "\\'") %>');.
Guffa,


22

Możesz użyć data:adresu URL w src:

var html = 'Hello from <img src="http://stackoverflow.com/favicon.ico" alt="SO">';
var iframe = document.querySelector('iframe');
iframe.src = 'data:text/html,' + encodeURIComponent(html);
<iframe></iframe>

Różnica między srcdoc = „…” i src = „data: text / html,…” w ramce iframe .

Konwertuj HTML na dane: link tekst / html za pomocą JavaScript .


1
Nie potrzebujesz nawet żadnego JavaScript: srcatrybut można podać w tekście, jeśli zostanie zmieniony, np. Używając rawurlencodew PHP:<iframe src="<?php echo htmlspecialchars('data:text/html,' . rawurlencode($content)); ?>"></iframe>
Jake

Firma Microsoft dodała obsługę tego rozwiązania prawie w tym samym czasie, w którym dodała obsługę srcdoc, i srcdocjest to lepszy sposób na zrobienie tego. Adresy URL danych są szeroko obsługiwane tylko w przypadku obrazów i CSS - o ile wiem, żadna wersja Internet Explorera nie obsługuje ich w ramkach iframe.
Abhi Beckert

6

W połączeniu z tym, co opisał Guffa, możesz użyć techniki opisanej w Wyjaśnieniu <script type = "text / template"> ... </script>, aby zapisać dokument HTML w specjalnym scriptelemencie (zobacz link do wyjaśnienia jak to działa). To dużo łatwiejsze niż przechowywanie dokumentu HTML w łańcuchu.


Po drugie, nie działałoby to zbyt dobrze w przypadku pełnego dokumentu HTML. Tagi takie jak <html>, <body>, <script>by zmylić tylko przeglądarkę, łamiąc renderowania dokumentu.
ximo,

To nie wydaje się być problemem, tagi HTML wewnątrz skryptów są ignorowane.
HBP

Masz rację :) Właściwie nie wypróbowałem jeszcze tej techniki, kiedy to pisałem, i musiałem skądś wziąć to założenie. Później dowiedziałem się, że wszystko w <script>tagu zostanie zignorowane przez przeglądarkę. Dzięki za poprawienie mnie!
ximo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.