javascript - Điều chỉnh chiều rộng và chiều cao của iframe để phù hợp với nội dung bên trong nó
Tôi cần một giải pháp để tự động điều chỉnh chiều rộng và chiều cao của iframe để vừa khít với nội dung của nó. Vấn đề là chiều rộng và chiều cao có thể thay đổi sau khi iframe đã được tải. Tôi đoán tôi cần một hành động sự kiện để xử lý sự thay đổi kích thước của thân chứa trong iframe.
Câu trả lời #1
<script type="application/javascript">
function resizeIFrameToFitContent( iFrame ) {
iFrame.width = iFrame.contentWindow.document.body.scrollWidth;
iFrame.height = iFrame.contentWindow.document.body.scrollHeight;
}
window.addEventListener('DOMContentLoaded', function(e) {
var iFrame = document.getElementById( 'iFrame1' );
resizeIFrameToFitContent( iFrame );
// or, to resize all iframes:
var iframes = document.querySelectorAll("iframe");
for( var i = 0; i < iframes.length; i++) {
resizeIFrameToFitContent( iframes[i] );
}
} );
</script>
<iframe src="usagelogs/default.aspx" id="iFrame1"></iframe>
Câu trả lời #2
giải pháp một dòng cho nhúng: bắt đầu với kích thước tối thiểu và tăng lên theo kích thước nội dung. không cần thẻ script.
<iframe src="http://URL_HERE.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>Câu trả lời #3
Tiện ích jQuery đa trình duyệt.
Thư viện đa trình duyệt, đa miền có tên iframe-resizer sử dụng resizeObserver và mutationObserver để giữ kích thước iFrame phù hợp với nội dung và postMessage để giao tiếp giữa iFrame và trang chủ. Có các phiên bản cho React, Vue và jQuery.
Câu trả lời #4
Tất cả các giải pháp được đưa ra cho đến nay chỉ tính đến việc thay đổi kích thước một lần. Bạn đề cập rằng bạn muốn có thể thay đổi kích thước iFrame sau khi nội dung được chỉnh sửa. Để làm điều này, bạn cần thực hiện một hàm bên trong iFrame (khi nội dung thay đổi, bạn cần phát một sự kiện để thông báo rằng nội dung đã thay đổi).
Tôi đã gặp khó khăn với việc này trong một thời gian, vì mã bên trong iFrame dường như bị giới hạn trong DOM bên trong iFrame (và không thể chỉnh sửa iFrame), và mã thực thi bên ngoài iFrame lại bị giới hạn với DOM bên ngoài iFrame (và không thể bắt sự kiện đến từ bên trong iFrame).
Giải pháp xuất phát từ việc phát hiện ra (thông qua sự trợ giúp từ một đồng nghiệp) rằng jQuery có thể được chỉ định sử dụng DOM nào. Trong trường hợp này, DOM của cửa sổ cha.
Do đó, mã như thế này thực hiện những gì bạn cần (khi chạy bên trong iFrame):
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery("#IDofControlFiringResizeEvent").click(function () {
var frame = $('#IDofiframeInMainWindow', window.parent.document);
var height = jQuery("#IDofContainerInsideiFrame").height();
frame.height(height + 15);
});
});
</script>
Câu trả lời số 5
Nếu nội dung iframe đến từ cùng một miền, điều này sẽ hoạt động tốt. Tuy nhiên, nó đòi hỏi jQuery.
$('#iframe_id').load(function () {
$(this).height($(this).contents().height());
$(this).width($(this).contents().width());
});
Để làm cho nó thay đổi kích thước một cách linh hoạt, bạn có thể làm như sau:
<script language="javaScript">
<!--
function autoResize(){
$('#themeframe').height($('#themeframe').contents().height());
}
//-->
</script>
<iframe id="themeframe" onLoad="autoResize();" marginheight="0" frameborder="0" src="URL"></iframe>
Sau đó trên trang mà iframe tải, thêm cái này:
<script language="javaScript">
function resize()
{
window.parent.autoResize();
}
$(window).on('resize', resize);
</script>
Câu trả lời #6
Đây là một giải pháp tương thích nhiều trình duyệt nếu bạn không muốn sử dụng jQuery:
/**
* Resizes the given iFrame width so it fits its content
* @param e The iframe to resize
*/
function resizeIframeWidth(e){
// Set width of iframe according to its content
if (e.Document && e.Document.body.scrollWidth) //ie5+ syntax
e.width = e.contentWindow.document.body.scrollWidth;
else if (e.contentDocument && e.contentDocument.body.scrollWidth) //ns6+ & opera syntax
e.width = e.contentDocument.body.scrollWidth + 35;
else (e.contentDocument && e.contentDocument.body.offsetWidth) //standards compliant syntax - ie8
e.width = e.contentDocument.body.offsetWidth + 35;
}
Câu trả lời #7
Sau khi tôi đã thử mọi thứ trên đời, điều này thực sự hiệu quả với tôi.
index.html
<style type="text/css">
html, body{
width:100%;
height:100%;
overflow:hidden;
margin:0px;
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
function autoResize(iframe) {
$(iframe).height($(iframe).contents().find('html').height());
}
</script>
<iframe src="http://iframe.domain.com" width="100%" height="100%" marginheight="0" frameborder="0" border="0" scrolling="auto" onload="autoResize(this);"></iframe>
Câu trả lời #8
Ngữ cảnh
Tôi đã phải tự làm điều này trong bối cảnh một tiện ích mở rộng web. Tiện ích mở rộng web này chèn một phần giao diện người dùng vào mỗi trang, và giao diện người dùng này tồn tại bên trong một iframe. Nội dung bên trong iframe là động, vì vậy tôi đã phải điều chỉnh lại chiều rộng và chiều cao của chính iframe.
Tôi sử dụng React nhưng khái niệm này áp dụng cho mọi thư viện.
Giải pháp của tôi (điều này giả sử rằng bạn kiểm soát cả trang và iframe)
Bên trong iframe tôi đã thay đổi các kiểu body để có kích thước thực sự lớn. Điều này sẽ cho phép các phần tử bên trong bố trí sử dụng tất cả không gian cần thiết. Việc đặt width và height thành 100% không hiệu quả với tôi (tôi đoán là vì iframe có width=300px và height=150px mặc định)
/* something like this */
body {
width: 99999px;
height: 99999px;
}
Sau đó tôi chèn tất cả giao diện iframe vào trong một thẻ div và áp dụng một số kiểu cho nó
#ui-root {
display: 'inline-block';
}
Sau khi hiển thị ứng dụng của tôi bên trong #ui-root (trong React tôi làm việc này bên trong componentDidMount) tôi tính toán kích thước của div này và đồng bộ chúng với trang cha bằng window.postMessage:
let elRect = el.getBoundingClientRect()
window.parent.postMessage({
type: 'resize-iframe',
payload: {
width: elRect.width,
height: elRect.height
}
}, '*')
Trong khung bố tôi làm một việc gì đó như thế này:
window.addEventListener('message', (ev) => {
if(ev.data.type && ev.data.type === 'resize-iframe') {
iframe.style.width = ev.data.payload.width + 'px'
iframe.style.height = ev.data.payload.height + 'px'
}
}, false)
