加载时,jquery获得iframe内容的高度。

时间:2022-04-03 00:02:29

I have a Help page, help.php that I am loading inside an iframe in main.php How can I get the height of this page once it has loaded in the iframe?

我有一个帮助页面,帮助。我正在主框架内加载的php。php在iframe中加载后,如何获得页面的高度?

I am asking this because I can't style the height of to iframe to 100% or auto. That's why I think I need to use javascript.. I am using jQuery

我问这个是因为我不能将iframe的高度设置为100%或自动。这就是为什么我认为我需要使用javascript。我使用jQuery

CSS:

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:

JS:

$(document).ready(function () {
    $("a.open-help").click(function () {
        $(".help-div").show();
        return false;
    })
})

HTML:

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>

7 个解决方案

#1


91  

ok I finally found a good solution:

好的,我终于找到了一个好的解决方案:

$('iframe').load(function() {
    this.style.height =
    this.contentWindow.document.body.offsetHeight + 'px';
});

Because some browsers (older Safari and Opera) report onload completed before CSS renders you need to set a micro Timeout and blank out and reassign the iframe's src.

因为一些浏览器(旧的Safari和Opera)在CSS呈现之前完成了加载,所以你需要设置一个微超时,然后清空并重新分配iframe的src。

$('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';
}

#2


44  

The less complicated answer is to use .contents() to get at the iframe. Interestingly, though, it returns a different value from what I get using the code in my original answer, due to the padding on the body, I believe.

不太复杂的答案是使用.contents()来获取iframe。有趣的是,它返回的值与我在原始答案中使用代码时得到的值不同,因为我相信主体上的填充。

$('iframe').contents().height() + 'is the height'

This is how I've done it for cross-domain communication, so I'm afraid it's maybe unnecessarily complicated. First, I would put jQuery inside the iFrame's document; this will consume more memory, but it shouldn't increase load time as the script only needs to be loaded once.

这就是我在跨域通信中所做的,所以我担心这可能是不必要的复杂。首先,我将jQuery放在iFrame的文档中;这将消耗更多的内存,但是不应该增加加载时间,因为脚本只需要加载一次。

Use the iFrame's jQuery to measure the height of your iframe's body as early as possible (onDOMReady) and then set the URL hash to that height. And in the parent document, add an onload event to the iFrame tag that will look at the location of the iframe and extract the value you need. Because onDOMReady will always occur before the document's load event, you can be fairly certain the value will get communicated correctly without a race condition complicating things.

使用iFrame的jQuery尽可能早地测量iFrame的主体的高度(onDOMReady),然后将URL散列设置为该高度。在父文档中,向iFrame标记添加onload事件,该事件将查看iFrame的位置并提取所需的值。因为onDOMReady总是在文档的加载事件之前发生,所以您可以相当肯定,该值将在没有竞争条件的情况下得到正确的通信。

In other words:

换句话说:

...in Help.php:

…在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);

...and in the parent document:

…在父文档中:

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 );

#3


16  

I found the following to work on Chrome, Firefox and IE11:

我发现在Chrome, Firefox和IE11上的工作如下:

$('iframe').load(function () {
    $('iframe').height($('iframe').contents().height());
});

When the Iframes content is done loading the event will fire and it will set the IFrames height to that of its content. This will only work for pages within the same domain as that of the IFrame.

当加载iframe内容时,事件将触发,并将iframe高度设置为其内容的高度。这只适用于与IFrame相同域中的页面。

#4


5  

You don't need jquery inside the iframe to do this, but I use it cause the code is so much simpler...

在iframe中不需要jquery来实现这一点,但是我使用它导致代码更加简单……

Put this in the document inside your iframe.

把这个放到iframe中的文档中。

$(document).ready(function() {
  parent.set_size(this.body.offsetHeight + 5 + "px");  
});

added five above to eliminate scrollbar on small windows, it's never perfect on size.

在小窗口上增加了5个滚动条,它的大小从来都不完美。

And this inside your parent document.

在父文档中。

function set_size(ht)
{
$("#iframeId").css('height',ht);
}

#5


4  

The code to do this without jQuery is trivial nowadays:

现在,不用jQuery就能完成这个任务的代码很简单:

const frame = document.querySelector('iframe')
function syncHeight() {
  this.style.height = `${this.contentWindow.document.body.offsetHeight}px`
}
frame.addEventListener('load', syncHeight)

To unhook the event:

解开事件:

frame.removeEventListener('load', syncHeight)

#6


0  

this is the correct answer that worked for me

这是对我起作用的正确答案

$(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();
    });

#7


0  

Accepted answer's $('iframe').load will now produce a.indexOf is not a function error. Can be updated to:

接受答案的美元(“iframe”)。负载现在将产生a。indexOf不是函数错误。可以更新为:

$('iframe').on('load', function() {
  // ...
});

Few others similar to .load deprecated since jQuery 1.8: "Uncaught TypeError: a.indexOf is not a function" error when opening new foundation project

自jQuery 1.8:“未捕获的类型错误:a”以来,很少有类似于.load的东西被弃用。indexOf不是一个函数“在打开新的基础项目时出错”。

#1


91  

ok I finally found a good solution:

好的,我终于找到了一个好的解决方案:

$('iframe').load(function() {
    this.style.height =
    this.contentWindow.document.body.offsetHeight + 'px';
});

Because some browsers (older Safari and Opera) report onload completed before CSS renders you need to set a micro Timeout and blank out and reassign the iframe's src.

因为一些浏览器(旧的Safari和Opera)在CSS呈现之前完成了加载,所以你需要设置一个微超时,然后清空并重新分配iframe的src。

$('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';
}

#2


44  

The less complicated answer is to use .contents() to get at the iframe. Interestingly, though, it returns a different value from what I get using the code in my original answer, due to the padding on the body, I believe.

不太复杂的答案是使用.contents()来获取iframe。有趣的是,它返回的值与我在原始答案中使用代码时得到的值不同,因为我相信主体上的填充。

$('iframe').contents().height() + 'is the height'

This is how I've done it for cross-domain communication, so I'm afraid it's maybe unnecessarily complicated. First, I would put jQuery inside the iFrame's document; this will consume more memory, but it shouldn't increase load time as the script only needs to be loaded once.

这就是我在跨域通信中所做的,所以我担心这可能是不必要的复杂。首先,我将jQuery放在iFrame的文档中;这将消耗更多的内存,但是不应该增加加载时间,因为脚本只需要加载一次。

Use the iFrame's jQuery to measure the height of your iframe's body as early as possible (onDOMReady) and then set the URL hash to that height. And in the parent document, add an onload event to the iFrame tag that will look at the location of the iframe and extract the value you need. Because onDOMReady will always occur before the document's load event, you can be fairly certain the value will get communicated correctly without a race condition complicating things.

使用iFrame的jQuery尽可能早地测量iFrame的主体的高度(onDOMReady),然后将URL散列设置为该高度。在父文档中,向iFrame标记添加onload事件,该事件将查看iFrame的位置并提取所需的值。因为onDOMReady总是在文档的加载事件之前发生,所以您可以相当肯定,该值将在没有竞争条件的情况下得到正确的通信。

In other words:

换句话说:

...in Help.php:

…在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);

...and in the parent document:

…在父文档中:

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 );

#3


16  

I found the following to work on Chrome, Firefox and IE11:

我发现在Chrome, Firefox和IE11上的工作如下:

$('iframe').load(function () {
    $('iframe').height($('iframe').contents().height());
});

When the Iframes content is done loading the event will fire and it will set the IFrames height to that of its content. This will only work for pages within the same domain as that of the IFrame.

当加载iframe内容时,事件将触发,并将iframe高度设置为其内容的高度。这只适用于与IFrame相同域中的页面。

#4


5  

You don't need jquery inside the iframe to do this, but I use it cause the code is so much simpler...

在iframe中不需要jquery来实现这一点,但是我使用它导致代码更加简单……

Put this in the document inside your iframe.

把这个放到iframe中的文档中。

$(document).ready(function() {
  parent.set_size(this.body.offsetHeight + 5 + "px");  
});

added five above to eliminate scrollbar on small windows, it's never perfect on size.

在小窗口上增加了5个滚动条,它的大小从来都不完美。

And this inside your parent document.

在父文档中。

function set_size(ht)
{
$("#iframeId").css('height',ht);
}

#5


4  

The code to do this without jQuery is trivial nowadays:

现在,不用jQuery就能完成这个任务的代码很简单:

const frame = document.querySelector('iframe')
function syncHeight() {
  this.style.height = `${this.contentWindow.document.body.offsetHeight}px`
}
frame.addEventListener('load', syncHeight)

To unhook the event:

解开事件:

frame.removeEventListener('load', syncHeight)

#6


0  

this is the correct answer that worked for me

这是对我起作用的正确答案

$(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();
    });

#7


0  

Accepted answer's $('iframe').load will now produce a.indexOf is not a function error. Can be updated to:

接受答案的美元(“iframe”)。负载现在将产生a。indexOf不是函数错误。可以更新为:

$('iframe').on('load', function() {
  // ...
});

Few others similar to .load deprecated since jQuery 1.8: "Uncaught TypeError: a.indexOf is not a function" error when opening new foundation project

自jQuery 1.8:“未捕获的类型错误:a”以来,很少有类似于.load的东西被弃用。indexOf不是一个函数“在打开新的基础项目时出错”。