http://www.cnblogs.com/snandy/p/3902337.html

http://www.cnblogs.com/snandy/p/3900016.html

Snandy

Stop, thinking is the essence of progress.

同域iframe的高度自适应

  1. 引子
  2. 父页面里控制子页面
  3. 子页面里控制父页面

一、引子

我们先看一个示例,有两个页面,1.html通过iframe嵌入2.html,两个页面都是同域的

1.html

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8' />
    <title>1.html</title>
  </head>
  <body>
     <iframe id="ifr" src="2.html" frameborder="0" width="100%"></iframe>
  </body>
</html>

2.html,很多P元素将高度撑高一些

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>2.html</title>
  </head>
  <body>
     <p>这是一个ifrmae,嵌入在http://snandy.github.io/lib/iframe/1.html里 </p>
     <p>根据自身内容调整高度</p>
     <p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p>
  </body>
</html>

此时,浏览器访问1.html,效果如图

可以看到,嵌入的iframe出现了滚动条,需求是不想出现滚动条,页面多高就显示多少。我们不能随便给iframe设个高度,因为你不知道嵌入的iframe会有多高(内容是动态生成的)。

二、解决方法

解决方法其实很简单,无非是给1.html里的iframe设个高度,高度的值即为2.html的内容高度。要注意的是2.html的内容高度需要页面完全载入(onload)后获取。

有两种方式

A. JS代码写在父页面,即父页面(1.html)里获取子页面(2.html)文档对象,当iframe载入后(load)获取高度,将此高度值赋值给iframe标签

开始测试时使用iframe的contentWindow的load事件,但所有浏览器均不执行。最后使用iframe的load事件,在父页面1.html底部加入如下JS代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script type="text/javascript">
  // 计算页面的实际高度,iframe自适应会用到
  function calcPageHeight(doc) {
      var cHeight = Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)
      var sHeight = Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight)
      var height  = Math.max(cHeight, sHeight)
      return height
  }
  var ifr = document.getElementById('ifr')
  ifr.onload = function() {
      var iDoc = ifr.contentDocument || ifr.document
      var height = calcPageHeight(iDoc)
      ifr.style.height = height + 'px'
  }
</script>

这里有两个细节:

1. 取iframe内的文档对象,标准浏览器使用contentDocument属性,IE低版本(IE6,7,8)使用document属性。

2. calcPageHeight函数计算页面的实际高度,标准浏览器使用document.documentElement,低版本IE使用document.body,默认取clientHeight,出现滚动条的取scrollHeight,最后取两个值中最大的。

B. JS代码写在子页面,即子页面在window load后计算高度,将此高度值赋值给父页面的iframe

在子页面(2.html)底部加入如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
    // 计算页面的实际高度,iframe自适应会用到
    function calcPageHeight(doc) {
        var cHeight = Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)
        var sHeight = Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight)
        var height  = Math.max(cHeight, sHeight)
        return height
    }
    window.onload = function() {
        var height = calcPageHeight(document)
        parent.document.getElementById('ifr').style.height = height + 'px'     
    }
</script>

  

通过这两种方式都可以实现iframe的高度自适应,可以看到重新设置iframe的高度后,其滚动条都去掉了。

线上示例:http://snandy.github.io/lib/iframe/1.html

相关:

http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-78799536

http://msdn.microsoft.com/en-us/library/ie/cc196985(v=vs.85).aspx

 

Snandy

Stop, thinking is the essence of progress.

跨域iframe的高度自适应

1. 跨子域的iframe高度自适应

2. 完全跨域的iframe高度自适应

同域的我们可以轻松的做到

1. 父页面通过iframe的contentDocument或document属性访问到文档对象,进而可以取得页面的高度,通过此高度值赋值给iframe tag。

2. 子页面可以通过parent访问到父页面里引入的iframe tag,进而设置其高度。

但跨域的情况则不允许对子页面或父页面的文档进行访问(返回undefined),所以我们要做的就是打通或间接打通这个壁垒。

一、跨子域的iframe高度自适应

比如 'a.jd.com/3.html' 嵌入了 'b.jd.com/4.html',这种跨子域的页面

3.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8' />
    <title>1.html</title>
    <script type="text/javascript">
        document.domain = 'jd.com'
    </script>
  </head>
  <body>
     <iframe id="ifr" src="b.jd.com/4.html" frameborder="0" width="100%"></iframe>
  </body>
</html>

4.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>2.html</title>
    <script type="text/javascript">
        document.domain = 'jd.com'
    </script>
  </head>
  <body>
     <p>这是一个ifrmae,嵌入在3.html里 </p>
     <p>根据自身内容调整高度</p>
     <p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p><p>a</p>
<script>
    // 计算页面的实际高度,iframe自适应会用到
    function calcPageHeight(doc) {
        var cHeight = Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)
        var sHeight = Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight)
        var height  = Math.max(cHeight, sHeight)
        return height
    }
    window.onload = function() {
        var height = calcPageHeight(document)
        parent.document.getElementById('ifr').style.height = height + 'px'     
    }
</script>
  </body>
</html>

可以看到与上一篇对比,只要在两个页面里都加上document.domain就可以了

二、完全跨域的iframe高度自适应

分别有以下资源

这四个资源有如下关系

1. A里嵌入C,A和C是不同域的,即跨域iframe

2. C里嵌入B,C和B是不同域的,但A和B是同域的

3. C里嵌入D.js,D.js放在和A同域的项目里

通过一个间接方式实现,即通过一个隐藏的B.html来实现高度自适应。

A.html

嵌入页面C: http://snandy.jd-app.com

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8' />
    <title>A.html</title>
  </head>
  <body>
    <iframe id="ifr" src="http://snandy.jd-app.com" frameborder="0" width="100%"></iframe>
  </body>
</html>

B.html

嵌入在C页面中,它是隐藏的,通过parent.parent访问到A,再改变A的iframe(C.html)高度,这是最关键的,因为A,B是同域的所以可以访问A的文档对象等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8' />
    <title>B.html</title>
  </head>
  <body>
    <script type="text/javascript">
        window.onload = function() {
            var isSet = false
            var inteval = setInterval(function() {
                var search = location.search.replace('?''')
                if (isSet) {
                    clearInterval(inteval)
                    return  
                }
                if (search) {
                    var height = search.split('=')[1]
                    var doc = parent.parent.document
                    var ifr = doc.getElementById('ifr')
                    ifr.style.height = height + 'px'
                    isSet = true
                }
            }, 500)
        }
    </script>
  </body>
</html>

C.html

嵌入在A中,和A不同域,要实现C的自适应,C多高则A里的iframe就设为多高。C里嵌入B.html 和 D.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!doctype html>
<html>
<head>
    <title>C.html</title>
    <meta charset="utf-8">
</head>
<body>
    <h3>这是一个很长的页面,我要做跨域iframe的高度自适应</h3>
    <ul>
        <li>页面 A:http://snandy.github.io/lib/iframe/A.html</li>
        <li>页面 B:http://snandy.github.io/lib/iframe/B.html</li>
        <li>页面 C:http://snandy.jd-app.com</li>
        <li>D.js:http://snandy.github.io/lib/iframe/D.js</li>
    </ul>
    <p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p>
    <iframe id="myifr" style="display:none" src="http://snandy.github.io/lib/iframe/B.html"></iframe>
    <script type="text/javascript" src="http://snandy.github.io/lib/iframe/D.js"></script>
</body>
</html>

  

D.js

在页面C载入后计算其高度,然后将计算出的height赋值给C里引入的iframe(B.html)的src

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 计算页面的实际高度,iframe自适应会用到
function calcPageHeight(doc) {
    var cHeight = Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)
    var sHeight = Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight)
    var height  = Math.max(cHeight, sHeight)
    return height
}
window.onload = function() {
    var doc = document
    var height = calcPageHeight(doc)
    var myifr = doc.getElementById('myifr')
    if (myifr) {
        myifr.src = 'http://snandy.github.io/lib/iframe/B.html?height=' + height
        // console.log(doc.documentElement.scrollHeight)     
    }
};

  

线上示例:http://snandy.github.io/lib/iframe/A.html

iframe的高度自适应的更多相关文章

  1. 跨域iframe的高度自适应

    If you cannot hear the sound of the genuine in you, you will all of your life spend your days on the ...

  2. 同域iframe的高度自适应

    引子 父页面里控制子页面 子页面里控制父页面 一.引子 我们先看一个示例,有两个页面,1.html通过iframe嵌入2.html,两个页面都是同域的 1.html <!DOCTYPE html ...

  3. JQuery iframe宽高度自适应浏览器窗口大小的解决方法

    iframe宽高度自适应浏览器窗口大小的解决方法   by:授客 QQ:1033553122 1.   测试环境 JQuery-3.2.1.min.js 下载地址: https://gitee.com ...

  4. 让动态的 iframe 内容高度自适应

    使用iframe加载其他页面的时候,需要自适应iframe的高度 这里加载了两个不同内容高度的页面至iframe中 1. 没有设置高度 <div class="iframe-wrapp ...

  5. 实现iframe窗口高度自适应的又一个巧妙思路

    domainA 中有一个页面index.html,通过iframe嵌套了domainB中的一个页面other.html由于other.html页面在iframe中显示,而且其页面内容会动态的增加或减少 ...

  6. js获取iframe和父级之间元素,方法、属,获取iframe的高度自适应iframe高度

    摘自:http://blog.csdn.net/kongjiea/article/details/38870399 1.在父页面 获取iframe子页面的元素 (在同域的情况下 且在http://下测 ...

  7. Jquery-处理iframe的高度自适应

    超级简单的方法,也不用写什么判断浏览器高度.宽度啥的.下面的两种方法自选其一就行了.一个是放在和iframe同页面的,一个是放在test.html页面的.注意别放错地方了哦. iframe代码,注意要 ...

  8. 关于iframe的高度自适应问题(js)

    function SetCwinHeight() { var cwin=document.getElementById("cwin"); if (document.getEleme ...

  9. iframe高度自适应

    前两天在网上看到了一道面试题,问iframe高度自适应的问题.发现自己之前几乎没有关注过iframe的问题,所以在这里记录一下. 原题目是: 页面A的域名是:http://www.taobao.com ...

随机推荐

  1. 6个html5页面适配iphone6的技巧

    iphone6及iphone6plus已经出来一段时间了.很多移动端网站,以前写死body为320px的,现在估计也忙着做适配了. 大屏幕手机其实一直有,只是以前大家没怎么重视,移动端的H5页面大部分 ...

  2. ASP.NET MVC Html.Partial/Html.RenderPartial/Html.Action/Html.RenderAction区别

    1. @Html.Raw() 方法输出带有html标签的字符串: <div style="margin:10px 0px 0px;border:1px;border-color:red ...

  3. CAD迷你看图

    CAD迷你看图http://www.aec188.com/CAD迷你看图 2016R12超快.超小的CAD多功能看图工具,完全脱离AutoCAD浏览R14-R2016各版本DWG/DXF/DWF的二三 ...

  4. sqlite数据类型

    sqlite数据类型(时间 日期 double等)     sqlite3支持的数据类型: NULL.INTEGER.REAL.TEXT.BLOB但是,sqlite3也支持如下的数据类型smallin ...

  5. python jar

    jpype不好用 pyjnius pip install jnius pip install cython

  6. org.springframework.web.context.ContextLoaderListener(转载)

    ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息.因为它实现了ServletContextListener这个接口,在web ...

  7. 编写HTML表单提交并接受数据信息(获取用户通过表单提交的内容)

    MyInfoForm.java package com.fxl; import java.io.IOException; import java.io.PrintWriter; import java ...

  8. Jquery 中 ajaxSubmit使用讲解(转)

    1 ,引入依赖脚本 <script type="text/javascript" src="/js/jquery/jquery.form.js">& ...

  9. nodejs gulp less编辑

    nodejs 下载地址:http://pan.baidu.com/s/1bnz2oPp 提取密码:0mip 1.最简单的编译less 在安装好nodejs后,cmd 进入控制台 安装 lessc : ...

  10. Rhel6-varnish配置文档

    系统环境: rhel6 x86_64 iptables and selinux disabled 主机: 192.168.122.160:virnish apache server60.example ...