现在的位置: 首页 > 综合 > 正文

js 操作 Iframe (跨域,高度自动适应)

2012年10月23日 ⁄ 综合 ⁄ 共 3940字 ⁄ 字号 评论关闭
文章目录

很多人一直都有个想法,要是可以随心所欲的操作iframe就好了。这样静态页面也就有了相当于后台动态页面php,jsp,asp中include,require实现统一多页面布局的能力。

通过Javascript的帮忙我们可以像后台一样动态加载操作iframe对象属性src指向的html页面的内容。这样的操作需要提供两个页面,一个页面是iframe所在页面(页面名称:iPage.html),另一个页面是iframe属性src指向页面(页面名称:srcPage.html)。

iPage.html,<body>里dom:

  1. <iframeid=iIdname=iNamesrc=srcPage.htmlscrolling=noframeborder=0></iframe>

srcPage.html,<body>里dom:

  1. <h1>妹妹的一天</h1> 
  2. <p>早上吃早点,中午约会吃饭,下午K歌,晚上和哥哥瞎折腾</p>

下面讨论ie下JS是怎么操作以上两个页面,再讨论firefox的做法,最后给出兼容ie,firefox浏览器操作iframe对象的方法。

 

一、ie下访问操作iframe里内容

 

大家都知道iframe是非标准html标签,它是由ie浏览器推出的多布局标签, 随后Mozilla也支持了这个标签。(闲话,嘿嘿)

1. ie通过document.frames["IframeName"]获取它,例子:我们在iPage.html里输出srcPage.html里h1的内容,JS如下:

  1. alert(document.frames["iName"].document.getElementsByTagName(h1)[0].firstChild.data);

你会发现这样在页面里加入代码,好像并没有输出想要的东东,为什么呢?这个我也没有搞清楚,只是习惯性的加入了window.onload就有输出了(注:JS代码都写到这个事件里去),知道的人士可否告诉我下。why?更改之后代码ie下有了输出,firefox下document.frames没有定义错误提示:

  1. window.onload = (function(){ 
  2.   alert(document.frames["iName"].document.getElementsByTagName(h1)[0].firstChild.data);
  3. });

2. ie另一种方法contentWindow获取它,代码:

  1. window.onload = (function(){ 
  2.  variObj = document.getElementById(iId).contentWindow;
  3.  alert(iObj.document.getElementsByTagName(h1)[0].firstChild.data);
  4. });

此方法经过ie6,ie7,firefox2.0,firefox3.0测试都通过,好事啊!嘿嘿。(网上一查,发现Mozilla Firefox iframe.contentWindow.focus缓冲区溢出漏洞,有脚本注入攻击的危险。

后来听说可以在后台防止这样的事情发生,算是松了口气。不过还是希望firefox新版本可以解决这样的危险。)

3.改变srcPage.html里h1标题内容,代码:

  1. iObj.document.getElementsByTagName(h1)[0].innerHTML=我想变成她一天的一部分;

通过contentWindow后访问里面的节点就和以前一样了。

二、firefox下访问操作iframe里内容

Mozilla支持通过IFrameElmRef.contentDocument访问iframe的document对象的W3C标准,通过标准可以少写一个document,代码:

  1. variObj = document.getElementById(iId).contentDocument;
  2. alert(iObj.getElementsByTagName(h1)[0].innerHTML=我想变成她一天的一部分);
  3. alert(iObj.getElementsByTagName(p)[0].firstChild.data);

兼容这两种浏览器的方法,现在也出来了,就是使用contentWindow这个方法。

嘿嘿!操作iframe是不是可以随心所欲了呢?如果还觉得不爽,你甚至可以重写iframe里的内容。

三、重写iframe里的内容

通过designMode(设置文档为可编辑设计模式)和contentEditable(设置内容为可编辑),你可以重写iframe里的内容。代码:

  1. variObj = document.getElementById(iId).contentWindow;
  2. iObj.document.designMode = On;
  3. iObj.document.contentEditable = true;
  4. iObj.document.open();
  5. iObj.document.writeln(<html><head>);
  6. iObj.document.writeln(<style>body {background:#000;font-size:9pt;margin: 2px; padding: 0px;}</style>);
  7. iObj.document.writeln(</head><body></body></html>);
  8. iObj.document.close();

这两个对象的资料可参考:http://msdn.microsoft.com/en-us/library/ms533720(VS.85).aspx

firebug测试以上代码性能

 

 

注释掉 iObj.document.designMode = ‘On’;

iObj.document.contentEditable = true;

 

效果没有变,时间效率是注释前的将近三倍。嘿嘿。那两个对象是参考网络一些人的写法,重写iframe里内容,其实没有必要用designMode和contentEditable,除非有其他的需求。

四、iframe自适应高度

有了上面的原理要实现这个相当简单,就是把iframe的height值设置成它里面文档的height值就可以。代码:

  1. window.onload = (function(){ 
  2. var iObj = document.getElementById(iId);
  3. iObj.heightiObj.contentWindow.document.documentElement.scrollHeight;
  4. });

// JavaScript Document
//** iframe自动适应页面 **//

//输入你希望根据页面高度自动调整高度的iframe的名称的列表
//用逗号把每个iframe的ID分隔. 例如: ["myframe1", "myframe2"],可以只有一个窗体,则不用逗号。

//定义iframe的ID
var iframeids=["main"]

//如果用户的浏览器不支持iframe是否将iframe隐藏 yes 表示隐藏,no表示不隐藏
var iframehide="yes"

function dyniframesize()
{
var dyniframe=new Array()
for (i=0; i<iframeids.length; i++)
{
if (document.getElementById)
{
//自动调整iframe高度
dyniframe[dyniframe.length] = document.getElementById(iframeids[i]);
if (dyniframe[i] && !window.opera)
{
dyniframe[i].style.display="block"
if (dyniframe[i].contentDocument && dyniframe[i].contentDocument.body.offsetHeight) //如果用户的浏览器是NetScape
dyniframe[i].height = dyniframe[i].contentDocument.body.offsetHeight;
else if (dyniframe[i].Document && dyniframe[i].Document.body.scrollHeight) //如果用户的浏览器是IE
dyniframe[i].height = dyniframe[i].Document.body.scrollHeight;
}
}
//根据设定的参数来处理不支持iframe的浏览器的显示问题
if ((document.all || document.getElementById) && iframehide=="no")
{
var tempobj=document.all? document.all[iframeids[i]] : document.getElementById(iframeids[i])
tempobj.style.display="block"
}
}
}

if (window.addEventListener)
window.addEventListener("load", dyniframesize, false)
else if (window.attachEvent)
window.attachEvent("onload", dyniframesize)
else
window.onload=dyniframesize

抱歉!评论已关闭.