ウェブサイトでブログページを開いています。問題は、iframeに幅を与えることができるが、iframeにスクロールバーがなく、1ページのように見えるように高さが動的でなければならないことです...
コンテンツの高さを計算するためにさまざまなJavaScriptコードを試しましたが、すべてのコードでaccess denied permissionエラーが発生し、役に立ちません。
<iframe src="http://bagtheplanet.blogspot.com/" name="ifrm" id="ifrm" width="1024px" ></iframe>
Ajaxを使用して高さを計算できますか、それともPHPを使用できますか?
2つのサブ質問に直接回答するには:いいえ、Ajaxでこれを行うことも、PHPで計算することもできません。
過去にやったことは、window.onload
のiframe'dページからのトリガーを使用して(画像の読み込みに時間がかかることがあるため、domready
ではありません)ページのボディの高さを親。
<body onload='parent.resizeIframe(document.body.scrollHeight)'>
すると、parent.resizeIframe
は次のようになります。
function resizeIframe(newHeight)
{
document.getElementById('blogIframe').style.height = parseInt(newHeight,10) + 10 + 'px';
}
そして、ページが完全にレンダリングされると、厄介なcontentdocument
vs contentWindow
をいじることなくトリガーする堅牢なリサイザーがあります:)
確かに、最初はデフォルトの高さでiframeが最初に表示されますが、これは最初にiframeを非表示にして「読み込み中」の画像を表示するだけで簡単に処理できます。次に、resizeIframe
関数が起動したら、そこに2つの余分な行を追加して、読み込み中の画像を非表示にし、その偽のAjaxの外観のiframeを表示します。
もちろん、これは同じドメインからのみ機能するので、このものを埋め込むためのプロキシPHPスクリプトが必要な場合があります。 PHPを使用してサイトに直接フィードします。
JavaScriptでこれを行うことができます。
document.getElementById('foo').height = document.getElementById('foo').contentWindow.document.body.scrollHeight + "px";
IFRAMEコンテンツのフィッティングは、 Googleで検索 に簡単に対応できます。 1つのソリューション です:
<script type="text/javascript">
function autoIframe(frameId) {
try {
frame = document.getElementById(frameId);
innerDoc = (frame.contentDocument) ? frame.contentDocument : frame.contentWindow.document;
objToResize = (frame.style) ? frame.style : frame;
objToResize.height = innerDoc.body.scrollHeight + 10;
}
catch(err) {
window.status = err.message;
}
}
</script>
もちろん、これはあなたが持っているクロスドメインの問題を解決しません...設定document.domain
は、これらのサイトが同じ場所にある場合に役立ちます。ランダムなサイトをiframeしている場合、解決策はないと思います。
Firefox 3.6、Safari 4.0.4、およびInternet Explorer 7で動作するMooToolsを使用した問題の解決策を次に示します。
var iframe_container = $('iframe_container_id');
var iframe_style = {
height: 300,
width: '100%'
};
if (!Browser.Engine.trident) {
// IE has hasLayout issues if iframe display is none, so don't use the loading class
iframe_container.addClass('loading');
iframe_style.display = 'none';
}
this.iframe = new IFrame({
frameBorder: 0,
src: "http://www.youriframeurl.com/",
styles: iframe_style,
events: {
'load': function() {
var innerDoc = (this.contentDocument) ? this.contentDocument : this.contentWindow.document;
var h = this.measure(function(){
return innerDoc.body.scrollHeight;
});
this.setStyles({
height: h.toInt(),
display: 'block'
});
if (!Browser.Engine.trident) {
iframe_container.removeClass('loading');
}
}
}
}).inject(iframe_container);
「読み込み」クラスのスタイルを設定して、iframeコンテナの中央にAjax読み込みグラフィックを表示します。次に、Internet Explorer以外のブラウザーの場合、コンテンツの読み込みが完了すると、全高のIFRAMEが表示され、読み込み中のグラフィックが削除されます。
秘Theは、必要なすべてのiframeイベントを外部スクリプトから取得することです。たとえば、document.createElementを使用してiFrameを作成するスクリプトがあります。この同じスクリプトで、iFrameのコンテンツに一時的にアクセスできます。
var dFrame = document.createElement("iframe");
dFrame.src = "http://www.example.com";
// Acquire onload and resize the iframe
dFrame.onload = function()
{
// Setting the content window's resize function tells us when we've changed the height of the internal document
// It also only needs to do what onload does, so just have it call onload
dFrame.contentWindow.onresize = function() { dFrame.onload() };
dFrame.style.height = dFrame.contentWindow.document.body.scrollHeight + "px";
}
window.onresize = function() {
dFrame.onload();
}
これは、dFrameがこれらの関数のスコープ内に留まり、フレームのスコープ内から外部iFrame要素にアクセスできるため、実際のドキュメントの高さを確認し、必要に応じて拡張できるためです。この例はfirefoxで動作しますが、それ以外では動作しません。私はあなたに回避策を与えることができますが、あなたは残りを理解することができます;)
私はこれで3日間のレスリングの大部分を過ごしました。私は、固定ヘッダーと固定フッターを維持しながら、他のアプリケーションをそれ自体にロードするアプリケーションに取り組んでいます。ここに私が思いついたものがあります。 (EasyXDMも使用しましたが、成功しましたが、後でこのソリューションを使用するために引き出しました。)
このコードは、<iframe>
がDOMに存在した後に実行してください。 iframe(親)をプルするページに配置します。
// get the iframe
var theFrame = $("#myIframe");
// set its height to the height of the window minus the combined height of fixed header and footer
theFrame.height(Number($(window).height()) - 80);
function resizeIframe() {
theFrame.height(Number($(window).height()) - 80);
}
// setup a resize method to fire off resizeIframe.
// use timeout to filter out unnecessary firing.
var TO = false;
$(window).resize(function() {
if (TO !== false) clearTimeout(TO);
TO = setTimeout(resizeIframe, 500); //500 is time in miliseconds
});
以下は、私のonload
イベントハンドラです。
jQuery UI ダイアログ内でIFRAMEを使用します。異なる使用法では、いくつかの調整が必要になります。これは、Internet Explorer 8およびFirefox 3.5で(今のところ)私のためのトリックを行うようです。追加の調整が必要になる場合がありますが、一般的な考え方は明確である必要があります。
function onLoadDialog(frame) {
try {
var body = frame.contentDocument.body;
var $body = $(body);
var $frame = $(frame);
var contentDiv = frame.parentNode;
var $contentDiv = $(contentDiv);
var savedShow = $contentDiv.dialog('option', 'show');
var position = $contentDiv.dialog('option', 'position');
// disable show effect to enable re-positioning (UI bug?)
$contentDiv.dialog('option', 'show', null);
// show dialog, otherwise sizing won't work
$contentDiv.dialog('open');
// Maximize frame width in order to determine minimal scrollHeight
$frame.css('width', $contentDiv.dialog('option', 'maxWidth') -
contentDiv.offsetWidth + frame.offsetWidth);
var minScrollHeight = body.scrollHeight;
var maxWidth = body.offsetWidth;
var minWidth = 0;
// decrease frame width until scrollHeight starts to grow (wrapping)
while (Math.abs(maxWidth - minWidth) > 10) {
var width = minWidth + Math.ceil((maxWidth - minWidth) / 2);
$body.css('width', width);
if (body.scrollHeight > minScrollHeight) {
minWidth = width;
} else {
maxWidth = width;
}
}
$frame.css('width', maxWidth);
// use maximum height to avoid vertical scrollbar (if possible)
var maxHeight = $contentDiv.dialog('option', 'maxHeight')
$frame.css('height', maxHeight);
$body.css('width', '');
// correct for vertical scrollbar (if necessary)
while (body.clientWidth < maxWidth) {
$frame.css('width', maxWidth + (maxWidth - body.clientWidth));
}
var minScrollWidth = body.scrollWidth;
var minHeight = Math.min(minScrollHeight, maxHeight);
// descrease frame height until scrollWidth decreases (wrapping)
while (Math.abs(maxHeight - minHeight) > 10) {
var height = minHeight + Math.ceil((maxHeight - minHeight) / 2);
$body.css('height', height);
if (body.scrollWidth < minScrollWidth) {
minHeight = height;
} else {
maxHeight = height;
}
}
$frame.css('height', maxHeight);
$body.css('height', '');
// reset widths to 'auto' where possible
$contentDiv.css('width', 'auto');
$contentDiv.css('height', 'auto');
$contentDiv.dialog('option', 'width', 'auto');
// re-position the dialog
$contentDiv.dialog('option', 'position', position);
// hide dialog
$contentDiv.dialog('close');
// restore show effect
$contentDiv.dialog('option', 'show', savedShow);
// open using show effect
$contentDiv.dialog('open');
// remove show effect for consecutive requests
$contentDiv.dialog('option', 'show', null);
return;
}
//An error is raised if the IFrame domain != its container's domain
catch (e) {
window.status = 'Error: ' + e.number + '; ' + e.description;
alert('Error: ' + e.number + '; ' + e.description);
}
};
これを試してください、あなたはいつでも変更することができます。この例ではjQueryを使用します。
$('#iframe').live('mousemove', function (event) {
var theFrame = $(this, parent.document.body);
this.height($(document.body).height() - 350);
});
@SchizoDuckieの答えは非常にエレガントで軽量ですが、WebkitにはscrollHeightの実装がないため( here を参照)、Webkitベースのブラウザー(Safari、Chrome、さまざまなモバイルプラットフォーム)では機能しません。
この基本的な考え方がGeckoおよびTridentブラウザーとともにWebkitで機能するためには、置き換えるだけで済みます。
<body onload='parent.resizeIframe(document.body.scrollHeight)'>
と
<body onload='parent.resizeIframe(document.body.offsetHeight)'>
すべてが同じドメインにある限り、これは非常にうまく機能します。