Jak sprawić, by iframe reagował bez zakładania współczynnika proporcji? Na przykład treść może mieć dowolną szerokość lub wysokość, która jest nieznana przed renderowaniem.
Uwaga: możesz używać Javascript.
Przykład:
<div id="iframe-container">
<iframe/>
</div>
Zmień to iframe-container
tak, aby jego zawartość ledwo mieściła się w środku bez dodatkowej przestrzeni, innymi słowy, jest wystarczająco dużo miejsca na treść, aby można ją było wyświetlić bez przewijania, ale bez nadmiaru miejsca. Kontener idealnie otacza ramkę iframe.
To pokazuje, jak sprawić, by iframe reagował, zakładając, że proporcje treści wynoszą 16: 9. Ale w tym pytaniu współczynnik kształtu jest zmienny.
Odpowiedzi:
Nie można wchodzić w interakcje z ramką iFrame innego pochodzenia przy użyciu Javascript, aby uzyskać jej rozmiar; jedynym sposobem, aby to zrobić jest użycie
window.postMessage
wraz ztargetOrigin
zestawem do domeny lub wildchar*
od źródła iFrame. Możesz proxy zawartości różnych witryn źródłowych i używaćsrcdoc
, ale jest to uważane za włamanie i nie będzie działać z SPA i wieloma innymi bardziej dynamicznymi stronami.Rozmiar iFrame tego samego pochodzenia
Załóżmy, że mamy dwa iFrame tego samego pochodzenia, jeden o małej wysokości i stałej szerokości:
i iFrame o dużej wysokości:
Możemy uzyskać rozmiar iFrame przy
load
zdarzeniu, korzystając ziframe.contentWindow.document
tego, który wyślemy do okna nadrzędnego za pomocąpostMessage
:Otrzymamy odpowiednią szerokość i wysokość dla obu ramek iFrame; możesz to sprawdzić online tutaj i zobaczyć zrzut ekranu tutaj .
Hack innego rozmiaru iFrame pochodzenia ( niezalecany )
Opisana tutaj metoda to hack i należy jej użyć, jeśli jest to absolutnie konieczne i nie ma innej możliwości; nie będzie działać dla większości dynamicznie generowanych stron i SPA. Metoda pobiera kod źródłowy HTML strony za pomocą serwera proxy, aby ominąć zasady CORS (
cors-anywhere
jest to prosty sposób na utworzenie prostego serwera proxy CORS i ma wersję demonstracyjną onlinehttps://cors-anywhere.herokuapp.com
), a następnie wstrzykuje kod JS do tego HTML, aby użyćpostMessage
i wysłać rozmiar iFrame do dokumentu nadrzędnego. Obsługuje nawet zdarzenie iFrameresize
(w połączeniu z iFramewidth: 100%
) i przesyła rozmiar iFrame z powrotem do elementu nadrzędnego.patchIframeHtml
:Funkcja załatać i wstrzyknąć kod HTML iFrame zwyczaj JavaScript, który będzie używany
postMessage
do wysyłania rozmiar iFrame do rodzica naload
i naresize
. Jeśli parametr ma wartośćorigin
, wówczas<base/>
element HTML zostanie dodany do nagłówka przy użyciu tego początkowego adresu URL, dlatego też identyfikatory URI HTML/some/resource/file.ext
zostaną poprawnie pobrane przez pierwotny adres URL wewnątrz ramki iFrame.getIframeHtml
:Funkcja pozwalająca uzyskać HTML strony pomijający CORS za pomocą proxy, jeśli
useProxy
ustawiony jest parametr. Mogą istnieć dodatkowe parametry, które zostaną przekazanepostMessage
podczas wysyłania danych o rozmiarze.Funkcja obsługi zdarzenia komunikatu jest dokładnie taka sama, jak w opcji „Rozmiar iFrame tego samego pochodzenia” .
Możemy teraz załadować domenę pochodzącą z różnych źródeł w ramce iFrame z wprowadzonym niestandardowym kodem JS:
I dostosujemy ramkę iFrame do jej zawartości na pełną wysokość bez żadnego przewijania w pionie, nawet przy użyciu
overflow-y: auto
elementu iFrame ( powinno byćoverflow-y: hidden
tak, aby pasek przewijania nie migał przy zmianie rozmiaru ).Możesz to sprawdzić online tutaj .
Ponownie zauważmy, że jest to hack i należy go unikać ; nie możemy uzyskać dostępu do dokumentu iFrame Cross-Origin ani wstrzykiwać żadnych rzeczy.
źródło
cors-anywhere
w tej chwili nie działa, więc nie możesz wyświetlić strony demonstracyjnej . Nie chcę dodawać zrzutu ekranu strony zewnętrznej z powodów związanych z prawami autorskimi. Dodam inny serwer proxy CORS, jeśli pozostanie on długo wyłączony.Powoduje to wiele komplikacji w obliczaniu wielkości zawartości w ramce iframe, głównie ze względu na to, że CSS umożliwia robienie rzeczy, które mogą zepsuć sposób pomiaru wielkości zawartości.
Napisałem bibliotekę, która zajmuje się tymi wszystkimi rzeczami, a także działa między domenami, może być to pomocne.
https://github.com/davidjbradshaw/iframe-resizer
źródło
Moje rozwiązanie jest na GitHub i JSFiddle .
Przedstawienie rozwiązania dla responsywnego iframe bez założenia współczynnika proporcji.
Uwaga: nie zapomnij wywołać funkcji zmiany rozmiaru po załadowaniu strony, ponieważ sama wielkość okna nie jest zmieniana po załadowaniu strony.
Kod
index.html
style.css
main.js
Spędziłem nad tym trochę czasu. Mam nadzieję, że ci się spodoba =)
Edytuj To prawdopodobnie najlepsze ogólne rozwiązanie. Jednak gdy jest bardzo mały, element iframe nie ma odpowiedniego rozmiaru. Jest to specyficzne dla używanego elementu iframe. Nie jest możliwe zakodowanie poprawnej odpowiedzi na to zjawisko, chyba że masz kod iframe, ponieważ twój kod nie ma sposobu, aby wiedzieć, który rozmiar jest preferowany przez iframe, aby był poprawnie wyświetlany.
Tylko niektóre hacki, takie jak ten zaprezentowany przez @Christos Lytras, mogą dać radę, ale nigdy nie zadziała dla każdego elementu iframe. Tylko w określonej sytuacji.
źródło
Wykonaj jeden zestaw kontenerów iframe, ustaw właściwość CSS dla szerokości i wysokości
źródło