Article introduction of Wulin.com (www.vevb.com): Someone may not have encountered this problem yet. Let’s first explain what is adaptive height. The so-called iframe adaptive height means that based on the beauty of the interface and interaction, the border and scrollbar of the iframe are hidden, making it impossible to see that it is an iframe. If the iframe always calls the same fixed height page, we just need to write the iframe height to death. And
Search for iframe adaptive height through Google, with more than 5W results, search for iframe height adaptive height, with more than 2W results.I read through the dozens of articles in the previous articles and digged out a large number of reprints. There are three or five articles that are original. In these original articles, they basically only talk about how to adapt to static things, but they do not consider how to do dynamic synchronization after JS operates DOM. In addition, in terms of compatibility, the research has also been incomplete.
I hope to do some in-depth research in these two aspects.
Maybe someone hasn't come into contact with this problem yet. Let's explain first what is adaptive height. The so-called iframe adaptive height means that based on the beauty of the interface and interaction, the border and scrollbar of the iframe are hidden, making it impossible to see that it is an iframe. If the iframe always calls the same fixed height page, we just need to write the iframe height to death. If the iframe wants to switch pages, or the included page needs to perform DOM dynamic operations, the program needs to synchronize the iframe height and the actual height of the included page.
By the way, if you have to use the iframe, it will cause too much trouble to front-end development.
There are roughly two traditional practices:
Method 1: After each included page has been loaded by loading its own content, execute JS to obtain the height of this page, and then synchronize the iframe height of the parent page.
Method 2: Execute JS in the onload event of the main page iframe, get the height content of the included page, and then synchronize the height.
From the perspective of code maintenance, method two is better than method one, because method one, each included page has to introduce a piece of the same code to do this, and many copies have been created.
Both methods only deal with quiet things, that is, they are only executed when the content is loaded. If JS operates the height changes caused by the DOM, it is not very convenient.
If you do an Interval in the main window, constantly obtain the height of the included page, and then do synchronization, is it convenient and solve the problem of JS operating the DOM? The answer is yes.
Demo page: main page iframe_a.html, containing pages iframe_b.htm and iframe_c.html
Main page code example:
<iframe id=frame_content src=iframe_b.html scrolling=no frameborder=0></iframe><script type=text/javascript>
function reinitIframe(){
var iframe = document.getElementById(frame_content);
try{
iframe.height = iframe.contentWindow.document.documentElement.scrollHeight;
}catch (ex){}
}
window.setInterval(reinitIframe(), 200);
< /script> will there be any problem with the efficiency?
I did the test and opened 5 windows (IE6, IE7, FF, Opera, Safari) to execute this code, which will not have any impact on the CPU, and it will even be adjusted to 2ms, without any impact (basically maintained at 0% occupancy).
Let’s talk about the compatibility issues of each browser. How to get to the correct height. It is mainly worth comparing the two bodies.scrollHeight and documentElement.scrollHeight. Note that this article uses this doctype. Different doctypes should not affect the result, but if your page does not declare doctype, then add one first.
< !DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01//EN > Append the following test code to the main page to output these two values, code example:
<div><button>Check Height</button></div><script type=text/javascript>
function checkHeight() {
var iframe = document.getElementById(frame_content);
var bHeight = iframe.contentWindow.document.body.scrollHeight;
var dHeight = iframe.contentWindow.document.documentElement.scrollHeight;
alert(bHeight: + bHeight + , dHeight: + dHeight);
}
< /script> is loaded, and an absolutely positioned layer can be switched to change the page height dynamically. If the layer is expanded, the page height will be supported. Code example:
<div><button>Toggle Overlay</button>
< /div>
< div style=height:160px;position:relative>
< div id=overlay style=position:absolute;width:280px;height:280px;display:none;></div>
< /div>
<script type=text/javascript>
function toggleOverlay() {
var overlay = document.getElementById('overlay');
overlay.style.display = (overlay.style.display == 'none') ? 'block' : 'none';
}
< /script>The following lists the test values of the above code in each browser:
(bHeight = body.scrollHeight, dHeight = documentElement.scrollHeight, red = error value, green = correct value)
/ Layer is hidden when layer is expanded
bHeight dHeight bHeight dHeight
IE6 184 184 184 303
IE7 184 184 184 303
FF 184 184 184 303
Opera 181 181 300 300
Safari 184 184 303 184
Let’s ignore the problem that Opera is 3 pixels less than others… It can be seen that if there is no absolute positioning, the two values are equal, and it doesn’t matter which one you take.
But if there is, then the performance of each browser is different, and it is wrong to take any value alone. But one rule can be found, that is, take two maximum values and be compatible with each browser. So our main page code needs to be transformed into this:
function reinitIframe(){var iframe = document.getElementById(frame_content);
try{
var bHeight = iframe.contentWindow.document.body.scrollHeight;
var dHeight = iframe.contentWindow.document.documentElement.scrollHeight;
var height = Math.max(bHeight, dHeight);
iframe.height = height;
}catch (ex){}
}
window.setInterval(reinitIframe(), 200); In this way, the compatibility problem is basically solved. By the way, not only does the absolutely positioned layer affect the value, float will also cause the difference between the two values.
If you demonstrate the demo, you will find that in other browsers, except for IE, when the layer is expanded and then hidden, the height value obtained is still maintained at the expanded height of 303, rather than the true value hidden back 184, which means that it cannot shrink back after growing taller. This phenomenon can also occur when switching between different included pages. When switching from a high page to a low page, the height obtained is still the same high value.
It can be summarized as: when the height of the iframe form is higher than the actual height of the document, the height is taken as the height of the form, and when the height of the form is lower than the actual height of the document, the actual height of the document is taken as the actual height of the document. Therefore, it is necessary to find a way to set the height to a lower value than the actual document before synchronizing it. Therefore, add onload=this.height=100″ to the iframe, so that the page is short enough when loading, and then synchronize to the same height.
This value is determined in actual applications and is short enough but not too short, otherwise there will be obvious flickering in browsers such as FF. When the DOM is operated, the main page cannot be monitored, so the height can be reduced after the DOM is operated.
In one of my actual projects, I did not do this thing in terms of weighing costs and benefits, because I have to insert this code into each DOM function, which is too expensive, and in fact, it is not so fatal to shrink the layer or not shrink it. Including in the demo, this thing was not done. If the reader has a better way, please let me know.
Here is the code for the final main page:
<iframe id=frame_content src=iframe_b.html scrolling=no frameborder=0></iframe>
<script type=text/javascript>
function reinitIframe(){
var iframe = document.getElementById(frame_content);
try{
var bHeight = iframe.contentWindow.document.body.scrollHeight;
var dHeight = iframe.contentWindow.document.documentElement.scrollHeight;
var height = Math.max(bHeight, dHeight);
iframe.height = height;
}catch (ex){}
}
window.setInterval(reinitIframe(), 200);
< /script>