Tôi đã thử một vài giải pháp nhưng không thành công. Tôi tự hỏi liệu có giải pháp nào tốt hơn với một hướng dẫn dễ làm theo không.
Tôi đã thử một vài giải pháp nhưng không thành công. Tôi tự hỏi liệu có giải pháp nào tốt hơn với một hướng dẫn dễ làm theo không.
Câu trả lời:
Bạn có ba lựa chọn thay thế:
Đây là một thư viện đơn giản để giữ cho iFrames có kích thước phù hợp với nội dung của chúng. Nó sử dụng các API PostMessage và MutationObserver, dự phòng cho IE8-10. Nó cũng có các tùy chọn cho trang nội dung để yêu cầu iFrame chứa có kích thước nhất định và cũng có thể đóng iFrame khi bạn làm xong.
https://github.com/davidjbradshaw/iframe-resizer
Easy XDM sử dụng một bộ sưu tập các thủ thuật để cho phép giao tiếp miền chéo giữa các cửa sổ khác nhau trong một số trình duyệt và có các ví dụ để sử dụng nó để thay đổi kích thước iframe:
http://easyxdm.net/wp/2010/03/17/resize-iframe-based-on-content/
http://kinsey.no/blog/index.php/2010/02/19/resizing-iframes-using-easyxdm/
Easy XDM hoạt động bằng cách sử dụng PostMessage trên các trình duyệt hiện đại và giải pháp dựa trên Flash làm dự phòng cho các trình duyệt cũ hơn.
Xem thêm chủ đề này trên Stackoverflow (cũng có những chủ đề khác, đây là một câu hỏi thường gặp). Ngoài ra, Facebook dường như sẽ sử dụng một cách tiếp cận tương tự .
Một tùy chọn khác là gửi chiều cao iframe đến máy chủ của bạn và sau đó thăm dò ý kiến từ máy chủ đó từ trang web mẹ với JSONP (hoặc sử dụng một cuộc thăm dò dài nếu có thể).
Tôi có giải pháp để đặt chiều cao của iframe động dựa trên nội dung của nó. Điều này hoạt động cho nội dung tên miền chéo. Có một số bước cần thực hiện để đạt được điều này.
Giả sử bạn đã thêm iframe vào trang web "abc.com/page"
<div>
<iframe id="IframeId" src="http://xyz.pqr/contactpage" style="width:100%;" onload="setIframeHeight(this)"></iframe>
</div>
Tiếp theo, bạn phải ràng buộc sự kiện "tin nhắn" cửa sổ trong trang web "abc.com/page"
window.addEventListener('message', function (event) {
//Here We have to check content of the message event for safety purpose
//event data contains message sent from page added in iframe as shown in step 3
if (event.data.hasOwnProperty("FrameHeight")) {
//Set height of the Iframe
$("#IframeId").css("height", event.data.FrameHeight);
}
});
Khi tải iframe, bạn phải gửi tin nhắn đến nội dung cửa sổ iframe với thông báo "FrameHeight":
function setIframeHeight(ifrm) {
var height = ifrm.contentWindow.postMessage("FrameHeight", "*");
}
window.addEventListener('message', function (event) {
// Need to check for safety as we are going to process only our messages
// So Check whether event with data(which contains any object) contains our message here its "FrameHeight"
if (event.data == "FrameHeight") {
//event.source contains parent page window object
//which we are going to use to send message back to main page here "abc.com/page"
//parentSourceWindow = event.source;
//Calculate the maximum height of the page
var body = document.body, html = document.documentElement;
var height = Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight);
// Send height back to parent page "abc.com/page"
event.source.postMessage({ "FrameHeight": height }, "*");
}
});
Những gì tôi đã làm là so sánh Chiều rộng khung nội tuyến cho đến khi nó thay đổi kích thước trong khi tôi tăng dần Chiều cao khung nội tuyến. Và nó hoạt động tốt cho tôi. Bạn có thể điều chỉnh mức tăng thành bất kỳ thứ gì bạn muốn.
<script type="text/javascript">
function AdjustIFrame(id) {
var frame = document.getElementById(id);
var maxW = frame.scrollWidth;
var minW = maxW;
var FrameH = 100; //IFrame starting height
frame.style.height = FrameH + "px"
while (minW == maxW) {
FrameH = FrameH + 100; //Increment
frame.style.height = FrameH + "px";
minW = frame.scrollWidth;
}
}
</script>
<iframe id="RefFrame" onload="AdjustIFrame('RefFrame');" class="RefFrame"
src="http://www.YourUrl.com"></iframe>
Tôi có một tập lệnh bị rớt trong iframe với nội dung của nó. Nó cũng đảm bảo rằng iFrameResizer tồn tại (nó chèn nó dưới dạng tập lệnh) và sau đó thực hiện thay đổi kích thước.
Tôi sẽ đưa ra một ví dụ đơn giản bên dưới.
// /js/embed-iframe-content.js
(function(){
// Note the id, we need to set this correctly on the script tag responsible for
// requesting this file.
var me = document.getElementById('my-iframe-content-loader-script-tag');
function loadIFrame() {
var ifrm = document.createElement('iframe');
ifrm.id = 'my-iframe-identifier';
ifrm.setAttribute('src', 'http://www.google.com');
ifrm.style.width = '100%';
ifrm.style.border = 0;
// we initially hide the iframe to avoid seeing the iframe resizing
ifrm.style.opacity = 0;
ifrm.onload = function () {
// this will resize our iframe
iFrameResize({ log: true }, '#my-iframe-identifier');
// make our iframe visible
ifrm.style.opacity = 1;
};
me.insertAdjacentElement('afterend', ifrm);
}
if (!window.iFrameResize) {
// We first need to ensure we inject the js required to resize our iframe.
var resizerScriptTag = document.createElement('script');
resizerScriptTag.type = 'text/javascript';
// IMPORTANT: insert the script tag before attaching the onload and setting the src.
me.insertAdjacentElement('afterend', ifrm);
// IMPORTANT: attach the onload before setting the src.
resizerScriptTag.onload = loadIFrame;
// This a CDN resource to get the iFrameResizer code.
// NOTE: You must have the below "coupled" script hosted by the content that
// is loaded within the iframe:
// https://unpkg.com/iframe-resizer@3.5.14/js/iframeResizer.contentWindow.min.js
resizerScriptTag.src = 'https://unpkg.com/iframe-resizer@3.5.14/js/iframeResizer.min.js';
} else {
// Cool, the iFrameResizer exists so we can just load our iframe.
loadIFrame();
}
}())
Sau đó, nội dung iframe có thể được đưa vào bất kỳ đâu trong một trang / trang web khác bằng cách sử dụng tập lệnh như sau:
<script
id="my-iframe-content-loader-script-tag"
type="text/javascript"
src="/js/embed-iframe-content.js"
></script>
Nội dung iframe sẽ được đưa vào bên dưới bất cứ nơi nào bạn đặt thẻ script.
Hy vọng điều này là hữu ích cho ai đó. 👍
<script ... data-src="http://google.com">
và điền vào iframe src với nó.
iframe-resizer@4.2.10
Đây là giải pháp đơn giản của tôi tại trang này. http://lab.ohshiftlabs.com/iframesize/
Đây là cách nó làm việc;
Về cơ bản nếu bạn có thể chỉnh sửa trang ở tên miền khác, bạn có thể đặt một trang iframe khác thuộc về máy chủ của bạn để lưu chiều cao vào cookie. Với cookie đọc khoảng thời gian khi nó được cập nhật, hãy cập nhật chiều cao của khung nội tuyến. Đó là tất cả.
Tải xuống; http://lab.ohshiftlabs.com/iframesize/iframesizepost.zip
Chỉnh sửa: Tháng 12 2019
Giải pháp ở trên về cơ bản sử dụng một iframe khác bên trong iframe thứ 3 của iframe thuộc về miền trang trên cùng mà bạn gọi là trang này với chuỗi truy vấn lưu giá trị kích thước vào cookie, trang bên ngoài kiểm tra truy vấn này với một khoảng thời gian. Nhưng nó không phải là một giải pháp tốt, vì vậy bạn nên làm theo một trong những cách sau:
Trong trang đầu:
window.addEventListener("message", (m)=>{iframeResizingFunction(m)});
Ở đây bạn có thể kiểm tra m.origin
xem nó đến từ đâu.
Trong trang khung:
window.parent.postMessage({ width: 640, height:480 }, "*")
Mặc dù, xin đừng quên rằng đây không phải là cách an toàn. Để đảm bảo an toàn, hãy cập nhật giá trị * (targetOrigin) với giá trị mong muốn của bạn. Vui lòng làm theo tài liệu: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
Tôi đã tìm thấy một giải pháp phía máy chủ khác dành cho nhà phát triển web sử dụng PHP để lấy kích thước của iframe.
Đầu tiên là sử dụng tập lệnh máy chủ PHP cho một cuộc gọi bên ngoài thông qua hàm bên trong: (giống như file_get_contents
với nhưng curl và dom).
function curl_get_file_contents($url,$proxyActivation=false) {
global $proxy;
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7");
curl_setopt($c, CURLOPT_REFERER, $url);
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
if($proxyActivation) {
curl_setopt($c, CURLOPT_PROXY, $proxy);
}
$contents = curl_exec($c);
curl_close($c);
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
@$dom->loadHTML($contents);
$form = $dom->getElementsByTagName("body")->item(0);
if ($contents) //si on a du contenu
return $dom->saveHTML();
else
return FALSE;
}
$url = "http://www.google.com"; //Exernal url test to iframe
<html>
<head>
<script type="text/javascript">
</script>
<style type="text/css">
#iframe_reserve {
width: 560px;
height: 228px
}
</style>
</head>
<body>
<div id="iframe_reserve"><?php echo curl_get_file_contents($url); ?></div>
<iframe id="myiframe" src="http://www.google.com" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" style="overflow:none; width:100%; display:none"></iframe>
<script type="text/javascript">
window.onload = function(){
document.getElementById("iframe_reserve").style.display = "block";
var divHeight = document.getElementById("iframe_reserve").clientHeight;
document.getElementById("iframe_reserve").style.display = "none";
document.getElementById("myiframe").style.display = "block";
document.getElementById("myiframe").style.height = divHeight;
alert(divHeight);
};
</script>
</body>
</html>
Bạn cần hiển thị dưới div ( iframe_reserve
) html được tạo bởi lệnh gọi hàm bằng cách sử dụngecho curl_get_file_contents("location url iframe","activation proxy")
Sau khi thực hiện việc này, một hàm sự kiện nội dung được tải lên với javascript lấy chiều cao của khung nội tuyến của trang chỉ bằng một điều khiển đơn giản đối với nội dung div ( iframe_reserve
)
Vì vậy, tôi đã sử dụng divHeight = document.getElementById("iframe_reserve").clientHeight;
để lấy chiều cao của trang bên ngoài mà chúng tôi sẽ gọi sau khi che vùng chứa div ( iframe_reserve
). Sau đó, chúng tôi tải iframe với chiều cao tốt của nó.
Tôi gặp sự cố này khi đang làm việc gì đó tại nơi làm việc (sử dụng React). Về cơ bản, chúng tôi có một số nội dung html bên ngoài mà chúng tôi lưu vào bảng tài liệu của mình trong cơ sở dữ liệu và sau đó chèn vào trang trong một số trường hợp nhất định khi bạn đang ở trong tập dữ liệu Tài liệu.
Vì vậy, các dòng nội tuyến nhất định n
, trong đó n
có thể chứa html bên ngoài, chúng tôi cần thiết lập một hệ thống để tự động thay đổi kích thước iframe của mỗi nội tuyến sau khi nội dung được tải đầy đủ trong mỗi dòng. Sau khi quay bánh xe của tôi một chút, đây là cách tôi thực hiện nó:
message
sự kiện trong chỉ mục của ứng dụng React của chúng tôi để kiểm tra một khóa cụ thể mà chúng tôi sẽ đặt từ iframe của người gửi.<script>
thẻ sẽ đợi iframe window.onload
kích hoạt. Sau khi kích hoạt, chúng tôi sử dụng postMessage
để gửi thông báo đến cửa sổ mẹ với thông tin về id iframe, chiều cao được tính toán, v.v.id
của iframe mà chúng tôi truyền vào MessageEvent
đối tượngiframe
, chỉ cần đặt chiều cao từ giá trị được chuyển từ iframe postMessage
.// index
if (window.postMessage) {
window.addEventListener("message", (messageEvent) => {
if (
messageEvent.data.origin &&
messageEvent.data.origin === "company-name-iframe"
) {
const iframe = document.getElementById(messageEvent.data.id)
// this is the only way to ensure that the height of the iframe container matches its body height
iframe.style.height = `${messageEvent.data.height}px`
// by default, the iframe will not expand to fill the width of its parent
iframe.style.width = "100%"
// the iframe should take precedence over all pointer events of its immediate parent
// (you can still click around the iframe to segue, for example, but all content of the iframe
// will act like it has been directly inserted into the DOM)
iframe.style.pointerEvents = "all"
// by default, iframes have an ugly web-1.0 border
iframe.style.border = "none"
}
})
}
// in component that renders n iframes
<iframe
id={`${props.id}-iframe`}
src={(() => {
const html = [`data:text/html,${encodeURIComponent(props.thirdLineData)}`]
if (window.parent.postMessage) {
html.push(
`
<script>
window.onload = function(event) {
window.parent.postMessage(
{
height: document.body.scrollHeight,
id: "${props.id}-iframe",
origin: "company-name-iframe",
},
"${window.location.origin}"
);
};
</script>
`
)
}
return html.join("\n")
})()}
onLoad={(event) => {
// if the browser does not enforce a cross-origin policy,
// then just access the height directly instead
try {
const { target } = event
const contentDocument = (
target.contentDocument ||
// Earlier versions of IE or IE8+ where !DOCTYPE is not specified
target.contentWindow.document
)
if (contentDocument) {
target.style.height = `${contentDocument.body.scrollHeight}px`
}
} catch (error) {
const expectedError = (
`Blocked a frame with origin "${window.location.origin}" ` +
`from accessing a cross-origin frame.`
)
if (error.message !== expectedError) {
/* eslint-disable no-console */
console.err(
`An error (${error.message}) ocurred while trying to check to see ` +
"if the inner iframe is accessible or not depending " +
"on the browser cross-origin policy"
)
}
}
}}
/>