Spójrz na ten prosty kod HTML:
<div id="wrap1">
<iframe id="iframe1"></iframe>
</div>
<div id="warp2">
<iframe id="iframe2"></iframe>
</div>
Powiedzmy, że chciałem przesunąć folie, aby #wrap2
były przed #wrap1
. Elementy iframe są zanieczyszczane przez JavaScript. Znam jQuery .insertAfter()
i .insertBefore()
. Jednak gdy ich używam, element iFrame traci wszystkie zmienne i zdarzenia HTML i JavaScript.
Powiedzmy, że kod HTML elementu iFrame przedstawia się następująco:
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
// The variable below would change on click
// This represents changes on variables after the code is loaded
// These changes should remain after the iFrame is moved
variableThatChanges = false;
$(function(){
$("body").click(function(){
variableThatChanges = true;
});
});
</script>
</head>
<body>
<div id='anything'>Illustrative Example</div>
</body>
</html>
W powyższym kodzie zmienna variableThatChanges
... zmieniłaby się, gdyby użytkownik kliknął treść. Ta zmienna i zdarzenie kliknięcia powinny pozostać po przeniesieniu elementu iframe (wraz z innymi zmiennymi / zdarzeniami, które zostały uruchomione)
Moje pytanie jest następujące: w przypadku JavaScript (z jQuery lub bez), jak mogę przenieść węzły zawijania w DOM (i ich elementy potomne iframe), aby okno iFrame pozostało takie samo, a zdarzenia / zmienne / itp. Elementu iFrame pozostały podobnie?
źródło
inline-block
wyświetlaniem ... w tym miejscu zgaduję rozwiązanie ogólne (a właściwie stwierdzenie, że takie jest niemożliwe) byłoby najbardziej odpowiednie, biorąc pod uwagę zainteresowanie innych.Odpowiedzi:
Nie można przenieść elementu iframe z jednego miejsca w dom do drugiego bez jego ponownego ładowania.
Oto przykład pokazujący, że nawet przy użyciu natywnego JavaScript ramki iFrames nadal ładują się ponownie: http://jsfiddle.net/pZ23B/
var wrap1 = document.getElementById('wrap1'); var wrap2 = document.getElementById('wrap2'); setTimeout(function(){ document.getElementsByTagName('body')[0].appendChild(wrap1); },10000);
źródło
about:blank
, ale to, na czym mi zależy, to utrata zawartości wewnątrz ramki.$("#iframeid").contents()
jednak nie spowoduje to zapisania danych javascript, musiałby zostać wysłany na stronę nadrzędną przez iframe. (Lub strona nadrzędna musiałaby to pobrać z iframe)Dużo wyszukiwałem specyfikacji w3 / dom i nie znalazłem niczego ostatecznego, co konkretnie mówi, że ramka iframe powinna być przeładowywana podczas poruszania się po drzewie DOM, jednak znalazłem wiele odniesień i komentarzy w trac / bugzilla / microsoft w webkicie dotyczących różne zmiany zachowań na przestrzeni lat.
Mam nadzieję, że ktoś znajdzie coś konkretnego na ten temat, ale na razie oto moje ustalenia:
appendChild(node)
istniejący węzeł - tonode
jest najpierw usuwany z domeny.Ciekawostka tutaj -
IE<=8
nie przeładowano iframe - to zachowanie jest (trochę) nowe (odIE>=9
).Według komentarza Hallvord RM Steen , jest to cytat ze specyfikacji iframe
Jest to najbardziej zbliżona rzecz, jaką znalazłem w specyfikacji, jednak nadal wymaga pewnej interpretacji (ponieważ kiedy przenosimy
iframe
element w DOM, tak naprawdę nie robimy pełnegoremove
, nawet jeśli przeglądarki używają tejnode.removeChild
metody).źródło
Za każdym razem, gdy dołączany jest element iframe i ma zastosowany atrybut src, uruchamia akcję ładowania, podobnie jak podczas tworzenia tagu Image za pomocą JS. Więc kiedy je usuniesz, a następnie dołączysz, są to zupełnie nowe encje i odświeżają się. To rodzaj
window.location = window.location
ponownego załadowania strony.Jedyny znany mi sposób zmiany pozycji
iframes
to użycie CSS. Oto przykład, który stworzyłem, pokazujący jeden sposób rozwiązania tego problemuflex-box
: https://jsfiddle.net/3g73sz3k/15/Podstawowym pomysłem jest utworzenie
flex-box
opakowania, a następnie zdefiniowanie określonej kolejności elementów iframe przy użyciu atrybutu order w każdym opakowaniu iframe.<style> .container{ display: flex; flex-direction: column; } </style> <div class="container"> <div id="wrap1" style="order: 0" class="iframe-wrapper"> <iframe id="iframe1" src="https://google.com"></iframe> </div> <div id="warp2" style="order: 1" class="iframe-wrapper"> <iframe id="iframe2" src="https://bing.com"></iframe> </div> </div>
Jak widać na skrzypcach JS, te
order
style są wbudowane, aby uprościćflip
przycisk, więc obróćiframes
.Rozwiązanie pochodzi z tego pytania StackOverflow: Zamień pozycję DIV tylko za pomocą CSS
Mam nadzieję, że to pomoże.
źródło
Jeśli utworzyłeś element iFrame na stronie i chcesz po prostu przesunąć jego pozycję później, wypróbuj następujące podejście:
Dołącz element iFrame do treści i użyj wysokiego indeksu Z oraz góry, lewej, szerokości, wysokości, aby umieścić element iFrame w wybranym miejscu.
Nawet zoom CSS działa na ciele bez ponownego ładowania, co jest niesamowite!
Utrzymuję dwa stany dla mojego „widżetu” i jest on albo wstrzykiwany na miejscu w DOM, albo do ciała przy użyciu tej metody.
Jest to przydatne, gdy inna zawartość lub biblioteki zgniatają lub zgniatają element iFrame.
BUM!
źródło
Niestety,
parentNode
właściwość elementu HTML DOM jest tylko do odczytu. Oczywiście możesz dostosować pozycje elementów iframe, ale nie możesz zmienić ich położenia w DOM i zachować ich stanów.Zobacz ten jsfiddle, który stworzyłem, który zapewnia dobre łóżko testowe. http://jsfiddle.net/RpHTj/1/
Kliknij pole, aby przełączyć wartość. Kliknij „przenieś”, aby uruchomić javascript.
źródło
To pytanie jest dość stare ... ale znalazłem sposób na przeniesienie ramki iframe bez jej ponownego ładowania. Tylko CSS. Mam wiele ramek iframe ze strumieniami z kamery, nie lubię, gdy ładują się ponownie, gdy je zamieniam. Użyłem więc kombinacji pływających, pozycji: bezwzględnych i kilku fikcyjnych bloków, aby przenieść je bez ponownego ładowania i posiadania żądanego układu na żądanie (zmiana rozmiaru i wszystko).
źródło
W odpowiedzi na bounty @djechlin umieszczone na tym pytaniu rozwidliłem jsfiddle zamieszczone przez @ matt-h i doszedłem do wniosku, że nadal nie jest to możliwe.
http://jsfiddle.net/gr3wo9u6/
//this does not work, the frames reload when appended back to the DOM function swapFrames() { var w1 = document.getElementById('wrap1'); var w2 = document.getElementById('wrap2'); var f1 = w1.querySelector('iframe'); var f2 = w2.querySelector('iframe'); w1.removeChild(f1); w2.removeChild(f2); w1.appendChild(f2); w2.appendChild(f1); //f1.parentNode = w2; //f2.parentNode = w1; //alert(f1.parentNode.id); }
źródło
Jeśli używasz elementu iframe do uzyskiwania dostępu do stron, które kontrolujesz, możesz utworzyć skrypt javascript, aby umożliwić rodzicowi komunikowanie się z elementem iframe za pośrednictwem wiadomości postMessage
Stamtąd możesz zbudować login wewnątrz elementu iframe, aby zarejestrować zmiany stanu, a przed przeniesieniem dom, zażądać go jako obiektu json.
Po przeniesieniu element iframe zostanie ponownie załadowany, możesz przekazać dane stanu do elementu iframe, a element nasłuchujący elementu iframe może przeanalizować dane z powrotem do poprzedniego stanu.
źródło