Изменение размера перекрестного домена iframe
Я пытаюсь изменить параметр высоты iframe на те же px страницы, загружаемой в iframe. Страница, загружаемая в iframe, поступает из другого домена.
Внутри iframe будут загружены разные страницы, что приведет к изменению высоты содержимого iframe. Поэтому мне нужно будет захватить высоту содержимого iframe и применить его к параметру высоты iframe.
Вот пример того, о чем я говорю: http://jsfiddle.net/R7Yz9/3/
<div class="site"><a href="#" onclick="location.href='http://amazon.com/'; return false;" target="_top">Amazon </a></div>
<div class="site"><a href="#" onclick="location.href='http://cnn.com/'; return false;" target="_top">Cnn </a></div>
<div class="site"><a href="#" onclick="location.href='http://wikipedia.org/'; return false;" target="_top">Wikipedia </a></div>
<iframe id="source" src="http://amazon.com/" frameborder="0" scrolling="no" width="100%" height="100%"></iframe>
.
$(document).ready(function() {
var iframe = $( "#source" );
$( "a[target=_top]" ).click( function(){
iframe.attr( "src", this.href );
return false;
});
});
Ответы
Ответ 1
Вот небольшая библиотека, которая решает все проблемы с размером iFrames с содержащимся в них содержимым.
https://github.com/davidjbradshaw/iframe-resizer
Он рассматривает проблему с перекрестным доменом, используя API сообщений post-message, а также обнаруживает изменения в содержимом iFrame несколькими способами.
Работает во всех современных браузерах и IE8 вверх.
Ответ 2
Минимальный набор кроссдоменов, который я использовал для встраивания одного одиночного iframe на страницу.
На странице встраивания (содержащей iframe):
<iframe frameborder="0" id="sizetracker" src="http://www.hurtta.com/Services/SizeTracker/DE" width="100%"></iframe>
<script type="text/javascript">
// Create browser compatible event handler.
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen for a message from the iframe.
eventer(messageEvent, function(e) {
if (isNaN(e.data)) return;
// replace #sizetracker with what ever what ever iframe id you need
document.getElementById('sizetracker').style.height = e.data + 'px';
}, false);
</script>
На встроенной странице (iframe):
<script type="text/javascript">
function sendHeight()
{
if(parent.postMessage)
{
// replace #wrapper with element that contains
// actual page content
var height= document.getElementById('wrapper').offsetHeight;
parent.postMessage(height, '*');
}
}
// Create browser compatible event handler.
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen for a message from the iframe.
eventer(messageEvent, function(e) {
if (isNaN(e.data)) return;
sendHeight();
},
false);
</script>
Ответ 3
Вы получаете высоту содержимого iframe следующим образом:
iframe.contentWindow.document.body.scrollHeight
ОБНОВЛЕНИЕ
Однако могут возникнуть проблемы с кросс-доменом. Вот три источника, показывающие разные подходы:
http://css-tricks.com/cross-domain-iframe-resizing/
Как получить высоту перекрестного домена iframe
Получить значение поля ввода внутри iframe
Примечание: последние показывают, как получить доступ к полю, но принцип тот же, что и для доступа к высоте тела
Ответ 4
В javascript нет параметров для определения высоты междоменной высоты iframe, но вы можете сделать что-то подобное с помощью программирования на стороне сервера. Я использовал PHP для этого примера
<code>
<?php
$output = file_get_contents('http://yourdomain.com');
?>
<div id='iframediv'>
<?php echo $output; ?>
</div>
<iframe style='display:none' id='iframe' src="http://yourdomain.com" width="100%" marginwidth="0" height="100%" marginheight="0" align="top" scrolling="auto" frameborder="0" hspace="0" vspace="0"> </iframe>
<script>
if(window.attachEvent) {
window.attachEvent('onload', iframeResizer);
} else {
if(window.onload) {
var curronload = window.onload;
var newonload = function(evt) {
curronload(evt);
iframeResizer(evt);
};
window.onload = newonload;
} else {
window.onload = iframeResizer;
}
}
function iframeResizer(){
var result = document.getElementById("iframediv").offsetHeight;
document.getElementById("iframe").style.height = result;
document.getElementById("iframediv").style.display = 'none';
document.getElementById("iframe").style.display = 'inline';
}
</script>
</code>
Ответ 5
Если у вас есть доступ к манипуляции с кодом загружаемого вами сайта, следующее должно предоставить комплексный метод обновления высоты контейнера iframe
в любое время, когда высота изменений в кадре будет изменена.
Добавьте следующий код на страницы, которые вы загружаете (возможно, в заголовок). Этот код отправляет сообщение, содержащее высоту контейнера HTML, в любое время, когда DOM обновляется (если вы ленивы загружаете) или изменяется размер окна (когда пользователь изменяет браузер).
window.addEventListener("load", function(){
if(window.self === window.top) return; // if w.self === w.top, we are not in an iframe
send_height_to_parent_function = function(){
var height = document.getElementsByTagName("html")[0].clientHeight;
//console.log("Sending height as " + height + "px");
parent.postMessage({"height" : height }, "*");
}
// send message to parent about height updates
send_height_to_parent_function(); //whenever the page is loaded
window.addEventListener("resize", send_height_to_parent_function); // whenever the page is resized
var observer = new MutationObserver(send_height_to_parent_function); // whenever DOM changes PT1
var config = { attributes: true, childList: true, characterData: true, subtree:true}; // PT2
observer.observe(window.document, config); // PT3
});
Добавьте следующий код на страницу, на которой хранится iframe. Это обновит высоту iframe, учитывая, что сообщение пришло со страницы, которую загружает iframe.
<script>
window.addEventListener("message", function(e){
var this_frame = document.getElementById("healthy_behavior_iframe");
if (this_frame.contentWindow === e.source) {
this_frame.height = e.data.height + "px";
this_frame.style.height = e.data.height + "px";
}
})
</script>