Mam stronę pomocy, help.php, którą ładuję wewnątrz elementu iframe w main.php. Jak mogę uzyskać wysokość tej strony po załadowaniu jej do iframe?
Pytam o to, ponieważ nie mogę ustawić wysokości elementu iframe na 100% ani automatycznie. Dlatego myślę, że muszę używać javascript .. Używam jQuery
CSS:
body {
margin: 0;
padding: 0;
}
.container {
width: 900px;
height: 100%;
margin: 0 auto;
background: silver;
}
.help-div {
display: none;
width: 850px;
height: 100%;
position: absolute;
top: 100px;
background: orange;
}
#help-frame {
width: 100%;
height: auto;
margin:0;
padding:0;
}
JS:
$(document).ready(function () {
$("a.open-help").click(function () {
$(".help-div").show();
return false;
})
})
HTML:
<div class='container'>
<!-- -->
<div class='help-div'>
<p>This is a div with an iframe loading the help page</p>
<iframe id="help-frame" src="../help.php" width="100%" height="100%" frameborder="1"></iframe>
</div> <a class="open-help" href="#">open Help in iFrame</a>
<p>hello world</p>
<p>hello world</p>
<p>hello world</p>
<p>hello world</p>
<p>hello world</p>
</div>
Odpowiedzi:
ok w końcu znalazłem dobre rozwiązanie:
$('iframe').load(function() { this.style.height = this.contentWindow.document.body.offsetHeight + 'px'; });
Ponieważ niektóre przeglądarki (starsze Safari i Opera) raportują, że ładowanie zakończyło się przed renderowaniem CSS, musisz ustawić mikro limit czasu, wyczyścić i ponownie przypisać src elementu iframe.
$('iframe').load(function() { setTimeout(iResize, 50); // Safari and Opera need a kick-start. var iSource = document.getElementById('your-iframe-id').src; document.getElementById('your-iframe-id').src = ''; document.getElementById('your-iframe-id').src = iSource; }); function iResize() { document.getElementById('your-iframe-id').style.height = document.getElementById('your-iframe-id').contentWindow.document.body.offsetHeight + 'px'; }
źródło
real
rozmiardocument
wysokości, a niebody
wysokości. Używając jQuery możesz go pobrać$(this.contentWindow.document).height()
.Mniej skomplikowaną odpowiedzią jest użycie
.contents()
elementu iframe. Co ciekawe, zwraca inną wartość niż ta, którą otrzymałem, używając kodu w mojej pierwotnej odpowiedzi, ze względu na wypełnienie ciała, jak sądzę.$('iframe').contents().height() + 'is the height'
W ten sposób zrobiłem to do komunikacji między domenami, więc obawiam się, że może to być niepotrzebnie skomplikowane. Najpierw umieściłbym jQuery w dokumencie iFrame; spowoduje to zużycie większej ilości pamięci, ale nie powinno wydłużać czasu ładowania, ponieważ skrypt wystarczy załadować tylko raz.
Użyj jQuery elementu iFrame, aby zmierzyć wysokość treści elementu iframe tak wcześnie, jak to możliwe (onDOMReady), a następnie ustaw wartość skrótu adresu URL na tę wysokość. W dokumencie nadrzędnym dodaj
onload
zdarzenie do tagu iFrame, które sprawdzi położenie elementu iframe i wyodrębni potrzebną wartość. Ponieważ onDOMReady zawsze występuje przed zdarzeniem ładowania dokumentu, można być dość pewnym, że wartość zostanie przekazana poprawnie, bez sytuacji wyścigu komplikującej sytuację.Innymi słowy:
... w Help.php:
var getDocumentHeight = function() { if (location.hash === '') { // EDIT: this should prevent the retriggering of onDOMReady location.hash = $('body').height(); // at this point the document address will be something like help.php#1552 } }; $(getDocumentHeight);
... oraz w dokumencie nadrzędnym:
var getIFrameHeight = function() { var iFrame = $('iframe')[0]; // this will return the DOM element var strHash = iFrame.contentDocument.location.hash; alert(strHash); // will return something like '#1552' }; $('iframe').bind('load', getIFrameHeight );
źródło
<iframe src="../Help.php#introduction" />
)sleep(5)
w Help.php powinno być również dobrym sposobem na przetestowanie wszelkich warunków wyścigu. Jeśli element iframe w jakiś sposób uruchomił sięonLoad
wcześniejonDOMReady
, powinien pojawić się tutaj.Znalazłem następujące elementy do pracy w Chrome, Firefox i IE11:
$('iframe').load(function () { $('iframe').height($('iframe').contents().height()); });
Gdy zawartość ramek iframe zostanie załadowana, zdarzenie zostanie uruchomione, a wysokość ramek iframe zostanie ustawiona na wysokość jej zawartości. Będzie to działać tylko w przypadku stron w tej samej domenie, w której znajduje się domena iFrame.
źródło
Kod do zrobienia tego bez jQuery jest obecnie trywialny:
const frame = document.querySelector('iframe') function syncHeight() { this.style.height = `${this.contentWindow.document.body.offsetHeight}px` } frame.addEventListener('load', syncHeight)
Aby odczepić wydarzenie:
frame.removeEventListener('load', syncHeight)
źródło
Nie potrzebujesz do tego jquery wewnątrz elementu iframe, ale ja go używam, ponieważ kod jest o wiele prostszy ...
Umieść to w dokumencie wewnątrz elementu iframe.
$(document).ready(function() { parent.set_size(this.body.offsetHeight + 5 + "px"); });
dodano pięć powyżej, aby wyeliminować pasek przewijania w małych oknach, nigdy nie jest idealny pod względem rozmiaru.
I to w twoim dokumencie nadrzędnym.
function set_size(ht) { $("#iframeId").css('height',ht); }
źródło
to jest poprawna odpowiedź, która mi pomogła
$(document).ready(function () { function resizeIframe() { if ($('iframe').contents().find('html').height() > 100) { $('iframe').height(($('iframe').contents().find('html').height()) + 'px') } else { setTimeout(function (e) { resizeIframe(); }, 50); } } resizeIframe(); });
źródło
prosta jedna linijka zaczyna się od domyślnej minimalnej wysokości i zwiększa do rozmiaru zawartości.
<iframe src="http://url.html" onload='javascript:(function(o){o.style.height=o.contentWindow.document.body.scrollHeight+"px";}(this));' style="height:200px;width:100%;border:none;overflow:hidden;"></iframe>
źródło
Zaakceptowana odpowiedź
$('iframe').load
będzie teraz powodowaća.indexOf is not a function
błąd. Można zaktualizować do:$('iframe').on('load', function() { // ... });
Niewiele innych podobnych do
.load
przestarzałych od wersji jQuery 1.8: Błąd „Uncaught TypeError: a.indexOf nie jest funkcją” podczas otwierania nowego projektu podstawowegoźródło
Jest to rozwiązanie wolne od jQuery, które może współpracować ze SPA wewnątrz elementu iframe
document.getElementById('iframe-id').addEventListener('load', function () { let that = this; setTimeout(function () { that.style.height = that.contentWindow.document.body.offsetHeight + 'px'; }, 2000) // if you're having SPA framework (angularjs for example) inside the iframe, some delay is needed for the content to populate });
źródło
To jest moje przyjazne dla ES6 podejście bez jquery
document.querySelector('iframe').addEventListener('load', function() { const iframeBody = this.contentWindow.document.body; const height = Math.max(iframeBody.scrollHeight, iframeBody.offsetHeight); this.style.height = `${height}px`; });
źródło