欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

完美实现跨域Iframe高度自适应【Iframe跨域高度自适应解决方案】 要完全照着例子做 有大用 有大大用 有大大大用

 Iframe的强大功能偶就不多说了,它不但被开发人员经常运用,而且黑客们也常常使用它,总之用过的人知道它的强大之处,但是Iframe有个致命的“BUG”就是iframe的高度无法自动适应,这一点让很多人都头疼万分。百度或是谷歌一下,确实很多解决方法,但尝试一下,会发现问题很多:浏览器兼容性差,不能自适应,仅支持同域Iframe等诸多问题,尤其是跨域Iframe高度自适应问题。网上根本找不到一种可行的方案(唯一有一种提到加入代理页面的,经过测试发现无用)。难道真的没有一种可行的解决方案了吗? No,下面小鸣子和大家分享一种强大的方法,代码如下:

要完全照着下面的例子做,才行

[html] view plain copy
  1. <html>  

  2. <head>  

  3. <style>  

  4. body {margin-left: 0px;margin-top: 0px;margin-right: 0px;margin-bottom: 0px;overflow: hidden;}  

  5. </style>  

  6. </head>  

  7.   

  8. <body>  

  9. <iframe src='http://hi.baidu.com/' width='100%' height='100%' frameborder='0' name="_blank" id="_blank" ></iframe>  

  10.   

  11. </body>  

  12.   

  13. </html>  


代码强大之处:

1. 该方法完美兼容IE6,7,8 ,Fire fox,chrome,opera 等主流的浏览器;

2.同域,跨域皆支持;

3.不调用任何JS脚本;

注意三点.

1. 文件开头不能是


[html] view plain copy
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  

  2. <html xmlns="http://www.w3.org/1999/xhtml">  

2).文件开头同样不能是 

<!doctype html>
<html lang="zh-hans">




必须 是<html>开头





2. body样式中的 overflow: hidden; 绝对不对省略;


3.Iframe 中的 height='100%' 以及 滚动条不能设为no(默认是yes,不用设置即可)


 


好了,马上试试吧。100%不会让你失望。


来自 https://blog.csdn.net/nebear/article/details/51984368


跨域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

 

分类: JavaScript
16
0
« 上一篇:同域iframe的高度自适应
» 下一篇:Tip和菜单的实现方式

posted on 2014-08-12 07:35 snandy 阅读(25918) 评论(24编辑 收藏

评论

#1楼 2014-08-12 08:43 芬奇  


推荐+1
  


#2楼 2014-08-12 09:10 方方和圆圆  


受教了,原来是这样的,干货啊
  


#3楼 2014-08-12 09:59 bjhhh  


不太理解为什么要搞得这么复杂。
用样式表实现啦——

<style type="text/css">
body{background:#f00;}
body, html,#ifm1{width:100%;height:100%;overflow:hidden;margin:0;}
#ifm1{width:100%;height:100%;overflow:hidden;margin:0;}
</style>
<iframe id="ifm1" src='http://www.csdn.net' frameborder='no' scrolling='auto'></iframe>
  


#4楼 2014-08-12 10:16 龙恩0707  


  


#5楼 2014-08-12 10:33 冲杀  


我觉得你不一定非要用参数,可以试试用 #height-100-width-100的方式这样还不用重新刷新页面。
  


#6楼[楼主2014-08-12 11:54 snandy  


@ bjhhh
纯css实现,好方法,多谢。
但这种方式只适合纯iframe,当页头页尾有内容时就不行了。
  


#7楼 2014-08-12 13:37 烈火寒冰  


mark
  


#8楼 2014-08-12 15:18 [*王东*]  


mark
  


#9楼 2014-08-12 15:36 Tear Y  


2个网站都是可以自控制的话postMessage,window.name不是很好吗
  


#10楼 2014-08-12 17:05 sprintf  


mark 之
  


#11楼 2014-08-12 18:26 细品人生  


不错,收藏
  


#12楼[楼主2014-08-12 21:55 snandy  


@ 冲杀
有道理。
  


#13楼 2014-08-12 22:19 Tinkerc  


mark一下.
  


#14楼 2014-11-03 15:41 icelin  


C页面不是自己的页面,比如C页面是百度的页面,怎么在里边加代码啊,怎么实现跨域高度自适应啊
  


#15楼 2014-12-27 23:27 MissJacker  


MARK
  


#16楼 2015-06-03 10:01 jiangjunzhang  


线上实例挂了,提示“无法解析服务器的 DNS 地址”
  


#17楼[楼主2015-06-04 15:42 snandy  


@ jiangjunzhang
已修复,切换到新浪云
  


#18楼 2015-07-27 17:26 woowyl  


楼主,如果iframe里放得是外部网站,如法加自己的js怎么处理呢
  


#19楼 2015-07-27 17:36 woowyl  


无法添加自己的js
  


#20楼 2015-11-10 11:18 jay-lee  


前提两个域都是自己的代码才行,如果另一个域是外部的无法修改的代码,怎么跨越?
  


#21楼 2016-04-06 10:35 南宫千寻  


奇技淫巧,我服了
利用了URL可以向下传递信息,同域可以传递信息,好赞!!
  


#22楼 2016-04-28 11:13 shuying  


在同一个子域名下 当嵌套的页面有跳转时 建议 在计算height之前讲容器高度变为0
  


#23楼 2016-10-21 18:00 James2017  


@ icelin
引用C页面不是自己的页面,比如C页面是百度的页面,怎么在里边加代码啊,怎么实现跨域高度自适应啊

同问,是啊,不是自己的页面,如何做啊?

你有答案了吗?


来自  https://www.cnblogs.com/snandy/p/3900016.html



iframe之间通信问题及iframe自适应高度问题


下面本人来谈谈iframe之间通信问题及iframe自适应高度问题。

 1. iframe通信 分为:同域通信 和 跨域通信。所谓同域通信是指 http://localhost/demo/iframe/iframeA.html 下的a.html页面嵌套 iframe 比如: <iframe src="http://localhost/demo/iframe/iframeB.html" id="iframeA" name="iframeA">的B.html页面,这两个页面数据进行通信,比如我想在父页面A.html 调用子页面当中的函数 我们很容易想到或者google下 document.getElementById('iframeA').contentWindow.b(); 这种方法,其中b 是子页面B.html中的一个函数。但是这样调用下有个问题我纠结了很久,就是既然在火狐下报这样的错误, 如下:
 b不是个函数 但是我在子页面明明定义了这么一个函数,那么为什么会报这样的错误呢?经过仔细分析及google,发现有这么一个问题需要理解,当iframe没有加载完成后 我就去执行这个js会报这样的错误,所以就试着在火狐下 用iframe.onload 这个函数 进行测试,果然没有报错,是正确的 所以就确定是这个问题。所以就想写个兼容IE和火狐 google写个函数 来确定iframe已经加载完成!,其实给个回调函数来调用我们上面的方法。

综合上面的思路 就可以写个这样的代码:

复制代码
<iframe src="http://localhost/demo/iframe/iframeB.html" id="iframeA" name="iframeA"></iframe>
    <div id="topName">topNddddddddddddddddame</div>
    <script>
         function A(){
            alert("A");
        }
        var iframe = document.getElementById('iframeA');
        
        iframeIsLoad(iframe,function(){
            var obj = document.getElementById('iframeA').contentWindow;
            obj.b();
        });
        
            
        
        
     function iframeIsLoad(iframe,callback){
        if(iframe.attachEvent) {
            
            iframe.attachEvent('onload',function(){
                callback && callback();
            });
        }else {
            iframe.onload = function(){
                callback && callback();
            }
        }
     }

    </script>
复制代码

B.html 代码如下:

var b = function(){
            alert("B");
        }

2.子页面调用父页面的函数很简单,只要这样搞下就ok了,window.parent.A();

3. 子页面取父页面元素的值: window.parent.document.getElementById("topName").innerHTML等方法。

二: iframe跨域通信。

 iframe跨域访问一般分为2种情况,第一种是同主域,不同子域的跨域。 第二种是:不同主域跨域。

 一、 是同主域下面,不同子域之间的跨域;可以通过document.domain 来设置相同的主域来解决。

       假如现在我有个域 abc.example.com 下有个页面叫abc.html, 页面上嵌套了一个iframe 如下:<iframe src="http://def.example.com/demo/def.html"  id="iframe2" style="display:none;"></iframe>,我想在abc域下的页面abc.html 访问 def域下的def.html  我们都知道由于安全性 游览器的同源策略的限制,js不能操作页面不同域下 不同协议下 不同端口的页面,所以就要解决跨域访问了,假如父页面abc.html 页面有个js函数:function test(){console.log(1);}; 我想在子页面调用这个函数 还是按照上面的同域方式调用 parent.test();这样,通过在火狐下看 已经跨域了 解决的办法是 在各个js函数顶部 加一句 document.domain = 'example.com',就可以解决了。abc.html代码如下:

复制代码
<iframe src="http://def.example.com/demo/def.html"  id="iframe2" style="display:none;"></iframe>

// 跨域 子页调用父页的 函数 (假设是下面test函数)
document.domain = 'example.com';
function test(){console.log(1);};
复制代码

def.html代码如下:

复制代码
/*
 * 子页调用父页的方法
 */
document.domain = 'example.com';
//window.top.test();
window.parent.test();
复制代码

还是这两个页面 我想父页调用子页 如下方法:
a.html代码如下:

复制代码
/*
 * 跨域 父页想调用子页的的函数
 */
document.domain = 'example.com';
var iframe = document.getElementById('iframe2');
iframeIsLoad(iframe,function(){
    var obj = iframe.contentWindow;
         obj.child();
});
function iframeIsLoad(iframe,callback){
        if(iframe.attachEvent) {
            iframe.attachEvent('onload',function(){
                callback && callback();
            });
        }else {
            iframe.onload = function(){
                callback && callback();
            }
        }
 }
复制代码

假如现在def.html页面有个child函数 代码如下:

document.domain = 'example.com';
function child(){console.log('我是子页');}

就可以跨域调用了 不管是子页面调用父页面 还是父页面调用子页面。一切ok!

二、 是不同主域跨域;

 虽然google有几种方法关于不同主域上的跨域问题 有通过location.hash方法或者window.name方法或者html5及flash等等,但是我觉得下面iframe这种方法值得学习下,

如下图所示:域a.com的页面request.html(即http://a.com/demo/ajax/ajaxproxy/request.html)里面嵌套了一个iframe指向域b.com(http://b.com/demo/ajax/ajaxproxy/response.html)的response.html,而response.html里又嵌套了域a.com的proxy.html。

 

思路:要实现a.com域下的request.html页面请求域b.com下的process.php,可以将请求参数通过url传给response.html,由response.html向process.php发起真正的ajax请求(response.html与process.php都属于域b.com),然后将返回的结果通过url传给proxy.html,最后由于proxy.html和request.html是在同个域下,所以可以在proxy.html利用window.top 将结果返回在request.html完成真正的跨域。

 

ok, 先看看页面结构

a.com域下有:

     request.html

     proxy.html

b.com域下有:

    response.html

    process.php

先来看看request.html页面如下:

<!DOCTYPE HTML>
<html>
 <head>
  <title> New Document </title>
 </head>
     
 <body>
    <p id="result">这里将会填上响应的结果</p>
    <a id="sendBtn" href="javascript:void(0)">点击,发送跨域请求</a>
    <iframe id="serverIf" style="display:none"></iframe>
 
    <script>
        document.getElementById('sendBtn').onclick = function() {
            var url = 'http://b.com/demo/ajax/ajaxproxy/reponse.html',
                fn = 'GetPerson',          //这是定义在response.html的方法
                reqdata = '{"id" : 24}',   //这是请求的参数
                callback = "CallBack";     //这是请求全过程完成后执行的回调函数,执行最后的动作
 
            CrossRequest(url, fn, reqdata, callback);  //发送请求
        }
 
        function CrossRequest(url,fn,reqdata,callback) {
            var server = document.getElementById('serverIf');
            server.src = url + '?fn=' +encodeURIComponent(fn) + "&data=" +encodeURIComponent(reqdata) + "&callback="+encodeURIComponent(callback);
        }
        //回调函数
        function CallBack(data) {
            var str = "My name is " + data.name + ". I am a " + data.sex + ". I am " + data.age + " years old.";
             document.getElementById("result").innerHTML = str;
        }
    </script>
 </body>
</html>

  这个页面其实就是要告诉response.html:我要让你执行你定义好的方法GetPerson,并且要用我给你的参数'{"id" : 24}'。response.html纯粹是负责将CallBack这个方法名传递给下一位仁兄proxy.html,而proxy.html拿到了CallBack这个方法名就可以执行了,因为proxy.html和request.html是同域的。

response.html代码如下:

      

<!DOCTYPE HTML>
<html>
 <head>
  <title> New Document </title>
 </head>
 
 <body>
     <iframe id="proxy"></iframe>
    <script>
        // 通用方法 ajax请求
        function _request (reqdata,url,callback) {
            var xmlhttp;
            if(window.XMLHttpRequest) {
                xmlhttp = new XMLHttpRequest();
            }else {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
 
            xmlhttp.onreadystatechange = function(){
                if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    var data = xmlhttp.responseText;
                    callback(data);
                }
            }
            xmlhttp.open('POST',url);
            xmlhttp.setRequestHeader("Content-Type", "application/json; charset=utf-8");
            xmlhttp.send(reqdata);
        }
 
        // 通用方法 获取url参数
        function _getQuery(key) {
            var query = location.href.split('?')[1],
                value = decodeURIComponent(query.split(key + "=")[1].split("&")[0]);
            return value;
        }
 
        //向process.php发送ajax请求
        function GetPerson(reqdata,callback) {
            var url = 'http://b.com/demo/ajax/ajaxproxy/process.php';
            var fn = function(data) {
                var proxy = document.getElementById('proxy');
                proxy.src = "http://a.com/demo/ajax/ajaxproxy/Proxy.html?data=" + encodeURIComponent(data) + "&callback=" + encodeURIComponent(callback);
            };
            _request(reqdata, url, fn);
        }
 
        (function(){
            var fn = _getQuery('fn'),
                reqdata = _getQuery("data"),
                callback = _getQuery("callback");
           eval(fn + "('" + reqdata +"', '" + callback + "')");
        })();
    </script>
 </body>
</html>

  

      这里其实就是接收来自request.html的请求得到请求参数和方法后向服务器process.php发出真正的ajax请求,然后将从服务器返回的数据以及从request.html传过来的回调函数名传递给proxy.html。 

接下来看看php代码如下,其实就是想返回一个json数据:

<?php
    $data = json_decode(file_get_contents("php://input"));
    header("Content-Type: application/json; charset=utf-8");
    echo ('{"id" : ' . $data->id . ', "age" : 24, "sex" : "boy", "name" : "huangxueming"}');
?>

最后就是proxy.html代码:

<!DOCTYPE HTML>
<html>
 <head>
  <title> New Document </title>
 </head>
 
 <body>
    <script>
         function _getUrl(key) {//通用方法,获取URL参数
                       var query = location.href.split("?")[1],
                value = decodeURIComponent(query.split(key + "=")[1].split("&")[0]);
                    return value;
               }
         (function() {
             var callback = _getUrl("callback"),
                 data = _getUrl("data");
             eval("window.top." + decodeURIComponent(callback) + "(" + decodeURIComponent(data) + ")");
         })();
    </script>
 </body>
</html>

  这里也是最后一步了,proxy终于拿到了request.html透过response.html传过来的回调函数名以及从response.html直接传过来的响应数据,利用window.top执行request.html里定义的回调函数。

 三:iframe高度自适应的问题。

    iframe高度自适应分为2种,一种是同域下自适应  另外一种是跨域下自适应,下面我们来看看同域下iframe高度自适应的问题。

   1.同域下iframe高度自适应的问题:

        思路:获取被嵌套iframe元素,通过JavaScript取得被嵌套页面最终高度,然后在主页面进行设置来实现。

假如我们demo有iframe1.html和iframe2.html 下面贴上iframe1.html代码如下:

<!DOCTYPE HTML>
<html>
 <head>
  <title> New Document </title>
  <style>
    *{margin:0;padding:0;}
  </style>
 </head>
 
 <body>
    <iframe src="http://a.com/demo/ajax/iframeheight/iframe2.html" style="width:100%;border:1px solid #333;" frameborder="0" id="iframe"></iframe>
 
    <script>
        window.onload = function() {
            var iframeid = document.getElementById('iframe');
            if(iframeid && !window.opera) {
                if(iframeid.contentDocument && iframeid.contentDocument.body.offsetHeight) {
                    iframeid.height = iframeid.contentDocument.body.offsetHeight;
                }else if(iframeid.Document && iframeid.Document.body.scrollHeight){
                    iframeid.height = iframeid.Document.body.scrollHeight;
                }
            }
        }
    </script>
 </body>
</html>

iframe2.html

<!DOCTYPE HTML>
<html>
 <head>
  <title> New Document </title>
  <style>
    *{margin:0;padding:0;}
  </style>
 </head>
 
 <body>
    <div style="height:500px;"></div>
 </body>
</html>

就可以动态设置iframe1页面的高度为iframe2的高度了。

 2. 跨域下iframe高度自适应的问题。

    首先我们知道iframe跨域我们是不能用上面js方式来控制了,所以我们只能用个中间键 我们可以在a.com域下iframe1.html页面嵌套一个b.com域下的iframe2.html页面,然后我在iframe2.html页面嵌套个和iframe1.html相同域的iframe3.html页面了,这样的话 iframe1.html和iframe3.html就可以无障碍的进行通信了,因为页面iframe2.html嵌套iframe3.html,所以iframe2.html可以改写iframe3.html的href值。

   iframe1中的内容:

      iframe1.html内容主要接受iframe3.html页面传过来的内容并且去完成相应的操作。iframe1.html代码如下:

复制代码
<iframe src="http://b.com/demo/ajax/iframeheight/iframe2.html" style="width:400px;height:200px;" id="iframe"></iframe> 

<script>
   var ifr_el = document.getElementById("iframe");
   function getIfrData(data){
    ifr_el.style.height = data+"px";
   }
</script>
复制代码

 iframe2.html中的内容:

       iframe2.html内容是怎么把值传给iframe3.html页面,刚才说了是将值传递到iframe3.html页面的href中,所以只要修改iframe的src就可以,因为不用刷新C页面,所以可以用过hash的方式传递给iframe3.html页面.iframe2.html代码如下:

<!DOCTYPE HTML>
<html>
 <head>
  <title> New Document </title>
  <style>
    *{margin:0;padding:0;}
  </style>
 </head>
 
 <body>
    <iframe id="iframe" src="http://a.com/demo/ajax/iframeheight/iframe3.html" width="0" height="230px"></iframe>
 
    <script>
        var oldHeight = 0,
              ifr_el = document.getElementById("iframe");
         
        t && clearInterval(t);
        var t = setInterval(function(){
            var height = document.body.scrollHeight;
            if(oldHeight != height) {
                oldHeight = height;
                ifr_el.src += '#' +oldHeight;
            }
        },200);
    </script>
 </body>
</html>

         可以看到 默认情况下 iframe1.html 页面我给iframe2.html的高度是200像素 但是在iframe2.html我给iframe3.html高度是230像素,那么正常情况下是有滚动条的,那么现在我是想在iframe2.html获取滚动条的高度,把高度传给通过iframe3.html的src里面去,然后在iframe3.html页面里获取这个高度值 传给iframe1.html(因为iframe1.html和iframe3.html是同域的),所以iframe1.html能取到这个高度值,再设置下本身的高度就是这个值就ok了。

       iframe3.html页面的唯一功能就是接收iframe2.html页面通过href传进来的值并且传递给iframe1.html页面,可到iframe2.html页面传来的值可以通过一个定时器不停去查看location.href是 否被改变,但是这样感觉效率很低,还有个方式就是在新的浏览器中通过onhashchange事件 (IE8+,Chrome5.0+,Firefox3.6+,Safari5.0+,Opera10.6+)来监听href的改变。

iframe3.html代码如下:

<script>
    var oldHeight = 0;
 
    t && clearInterval(t);
    var t = setInterval(function(){
        var height = location.href.split('#')[1];
        if(height && height != oldHeight) {
            oldHeight = height;
            if(window.parent.parent.getIfrData) {
                window.parent.parent.getIfrData(oldHeight);
            }
        }
    },200);
    </script>

这样就可以解决通过跨域实现iframe自适应高度的问题了。

7
0
« 上一篇:javascript cookie
» 下一篇:web前端性能优化总结

ADD YOUR COMMENT

  1. #1楼 海之澜  2013-12-04 09:15
    好文,要顶,哈哈,学习了一下!

  2. #2楼 土豆哥哥  2014-08-12 22:51
    高手啊

  3. #3楼 世界万物  2016-07-29 18:16
    好方法 ,跟我想的基本一样

  4. #4楼 James2017  2016-10-21 18:01
    iframe套的页面不是自己能控制的页面,如百度,请问如何控制啊?
    有知道答案的大神吗?

  5. #5楼 暗夜心慌方  2016-11-15 10:09
    @ James2016
    我也遇到同样问题,请问你解决了没?

  6. #6楼 litblack  2018-01-02 14:53
    卧槽,坑,ifr_el.src += '#' +oldHeight; location.href.split('#')[1]; 获取不对

  7. #7楼[楼主] 龙恩0707  2018-01-02 23:00
    @ litblack
    自己多看看哪里不对哦

  8. #8楼 litblack  2018-01-03 10:34
    思路没问题,学习了,但有几点问题
    完全跨域获取高度:
    1、ifr_el.src += '#' +oldHeight,每次设置高度都应该取最后一个数值, location.href.split('#')[1];获取不对,
    2、document.body.scrollHeight 不同浏览器差别太大,可能包含boder的高度和marging高度,导致获取值不正确,



来自  http://www.cnblogs.com/tugenhua0707/p/3346522.html


普通分类: