利用JS对iframe父子(内外)页面进行操作的方法教程


Posted in Javascript onJune 15, 2017

本文主要给大家介绍了关于利用JS对iframe父子(内外)页面进行操作的方法,分享出来供大家参考学习,下面来一起看看详细的介绍:

一、获取iframe里的内容

在开始之前,首先我们来看看如何获取iframe里的内容,获取iframe中内容主要的两个API就是contentWindow,和contentDocument iframe.contentWindow, 获取iframe的window对象 iframe.contentDocument, 获取iframe的document对象 这两个API只是DOM节点提供的方式(即getELement系列对象)

var iframe = document.getElementById("iframe1");
 var iwindow = iframe.contentWindow;
 var idoc = iwindow.document;
  console.log("window",iwindow);//获取iframe的window对象
  console.log("document",idoc); //获取iframe的document
  console.log("html",idoc.documentElement);//获取iframe的html
  console.log("head",idoc.head); //获取head
  console.log("body",idoc.body); //获取body

实际情况如:

利用JS对iframe父子(内外)页面进行操作的方法教程

另外更简单的方式是,结合Name属性,通过window提供的frames获取.

<iframe src ="/index.html" id="ifr1" name="ifr1" scrolling="yes">
 <p>Your browser does not support iframes.</p>
</iframe>
<script type="text/javascript">
 console.log(window.frames['ifr1'].window);
console.dir(document.getElementById("ifr1").contentWindow);
</script>

其实window.frames[‘ifr1']返回的就是window对象,即

window.frames['ifr1']===window

这里就看你想用哪一种方式获取window对象,两者都行,不过本人更倾向于第二种使用frames[xxx].因为,字母少啊喂~ 然后,你就可以操控iframe里面的DOM内容。

二、在iframe中获取父级内容

同理,在同域下,父页面可以获取子iframe的内容,那么子iframe同样也能操作父页面内容。在iframe中,可以通过在window上挂载的几个API进行获取.

  • window.parent 获取上一级的window对象,如果还是iframe则是该iframe的window对象
  • window.top 获取最顶级容器的window对象,即,就是你打开页面的文档
  • window.self 返回自身window的引用。可以理解 window===window.self(脑残)

如图:

利用JS对iframe父子(内外)页面进行操作的方法教程

获取了之后,我们就可以进行相关操作了。 在同域的iframe中,我们可以巧妙的使用iframe的黑科技来实现一些trick.

iframe的轮询

话说在很久很久以前,我们实现异步发送请求是使用iframe实现的~! 怎么可能!!! 真的史料为证(自行google), 那时候为了不跳转页面,提交表单时是使用iframe提交的。现在,前端发展尼玛真快,websocket,SSE,ajax等,逆天skill的出现,颠覆了iframe, 现在基本上只能活在IE8,9的浏览器内了。 但是,宝宝以为这样就可以不用了解iframe了,而现实就是这么残酷,我们目前还需要兼容IE8+。所以,iframe 实现长轮询和长连接的trick 我们还是需要涉猎滴。

iframe长轮询

如果写过ajax的童鞋,应该知道,长轮询就是在ajax的readyState = 4的时,再次执行原函数即可。 这里使用iframe也是一样,异步创建iframe,然后reload, 和后台协商好, 看后台哥哥们将返回的信息放在,然后获取里面信息即可. 这里是直接放在body里.

var iframeCon = docuemnt.querySelector('#container'),
 text; //传递的信息
 var iframe = document.createElement('iframe'),
 iframe.id = "frame",
 iframe.style = "display:none;",
 iframe.name="polling",
 iframe.src="target.html";
 iframeCon.appendChild(iframe);
 iframe.onload= function(){
 var iloc = iframe.contentWindow.location,
 idoc = iframe.contentDocument;
 setTimeout(function(){
 text = idoc.getElementsByTagName('body')[0].textContent;
 console.log(text);
 iloca.reload(); //刷新页面,再次获取信息,并且会触发onload函数
 },2000);
 }

这样就可以实现ajax的长轮询的效果。 当然,这里只是使用reload进行获取,你也可以添加iframe和删除iframe的方式,进行发送信息,这些都是根据具体场景应用的。另外在iframe中还可以实现异步加载js文件,不过,iframe和主页是共享连接池的,所以还是很蛋疼的,现在基本上都被XHR和hard calllback取缔了,这里也不过多介绍了。

1.js在iframe子页面操作父页面元素代码:

window.parent.document.getElementByIdx_x("父页面元素id");

2.js在父页面获取iframe子页面元素代码如下:

window.frames["iframe_ID"].document.getElementByIdx_x("子页面元素id");

3. jquery在iframe子页面获取父页面元素代码如下:

$("#objid",parent.document)

4. jquery在父页面获取iframe子页面的元素

$("#objid",document.frames('iframename').document)

5.在iframe中调用父页面中定义的方法和变量:

window.parent.window.parentMethod();
window.parent.window.parentValue;

6.在父页面操作iframe子页面的方法和变量

window.frames["iframe_ID"].window.childMethod();
window.frames["iframe_ID"].window.childValue;

一、同域下父子页面的通信

父页面parent.html

<html>
<head>
 <script type="text/javascript">
  function say(){
   alert("parent.html");
  }
  function callChild(){
   myFrame.window.say();
   myFrame.window.document.getElementById("button").value="调用结束";
  }
 </script>
</head>
<body>
 <input id="button" type="button" value="调用child.html中的函数say()" onclick="callChild()"/>
 <iframe name="myFrame" src="http://caibaojian.com/child.html"></iframe>
</body>
</html>

子页面child.html

<html>
<head>
 <script type="text/javascript">
  function say(){
   alert("child.html");
  }
  function callParent(){
   parent.say();
   parent.window.document.getElementById("button").value="调用结束";
  }
 </script>
</head>
<body>
 <input id="button" type="button" value="调用parent.html中的say()函数" onclick="callParent()"/>
</body>
</html>

注意事项

要确保在iframe加载完成后再进行操作,如果iframe还未加载完成就开始调用里面的方法或变量,会产生错误。判断iframe是否加载完成有两种方法:

      1. iframe上用onload事件

      2. 用document.readyState=="complete"来判断

二、跨域父子页面通信方法

如果iframe所链接的是外部页面,因为安全机制就不能使用同域名下的通信方式了。

1.父页面向子页面传递数据

实现的技巧是利用location对象的hash值,通过它传递通信数据。在父页面设置iframe的src后面多加个data字符串,然后在子页面中通过某种方式能即时的获取到这儿的data就可以了,例如:

1.1 在子页面中通过setInterval方法设置定时器,监听location.href的变化即可获得上面的data信息

1.2. 然后子页面根据这个data信息进行相应的逻辑处理

2.子页面向父页面传递数据

实现技巧就是利用一个代理iframe,它嵌入到子页面中,并且和父页面必须保持是同域,然后通过它充分利用上面第一种通信方式的实现原理就把子页面的数据传递给代理iframe,然后由于代理的iframe和主页面是同域的,所以主页面就可以利用同域的方式获取到这些数据。使用 window.top或者window.parent.parent获取浏览器最顶层window对象的引用。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jQuery LigerUI 使用教程入门篇
Jan 18 Javascript
JavaScript的Module模式编程深入分析
Aug 13 Javascript
jQuery如何解决IE输入框不能输入的问题
Oct 08 Javascript
微信小程序 scroll-view组件实现列表页实例代码
Dec 14 Javascript
Vue.Draggable实现拖拽效果
Jul 29 Javascript
Angularjs Promise实例详解
Mar 15 Javascript
微信小程序将字符串生成二维码图片的操作方法
Jul 17 Javascript
轻松解决JavaScript定时器越走越快的问题
May 13 Javascript
layui实现下拉框三级联动
Jul 26 Javascript
Vue防止白屏添加首屏动画的实例
Oct 31 Javascript
JavaScript实现移动端弹窗后禁止滚动
May 25 Javascript
在antd Form表单中select设置初始值操作
Nov 02 Javascript
使用Require.js封装原生js轮播图的实现代码
Jun 15 #Javascript
JavaScript实现选中文字提示新浪微博分享效果
Jun 15 #Javascript
详解vue跨组件通信的几种方法
Jun 15 #Javascript
Bootstrap响应式导航由768px变成992px的实现代码
Jun 15 #Javascript
javascript完美实现给定日期返回上月日期的方法
Jun 15 #Javascript
JS自动生成动态HTML验证码页面
Jun 14 #Javascript
自定义vue全局组件use使用、vuex的使用详解
Jun 14 #Javascript
You might like
PHP性能优化工具篇Benchmark类调试执行时间
2011/12/06 PHP
php中自定义函数dump查看数组信息类似var_dump
2014/01/27 PHP
php正则提取html图片(img)src地址与任意属性的方法
2017/02/08 PHP
php pdo操作数据库示例
2017/03/10 PHP
PHP大文件切割上传并带进度条功能示例
2019/07/01 PHP
jquery获取URL中参数解决中文乱码问题的两种方法
2013/12/18 Javascript
动态加载iframe时get请求传递中文参数乱码解决方法
2014/05/07 Javascript
js实现头像图片切割缩放及无刷新上传图片的方法
2015/07/17 Javascript
jQuery控制frames及frame页面JS的方法
2016/03/08 Javascript
Bootstrap组件学习之导航、标签、面包屑导航(精品)
2016/05/17 Javascript
原生js实现可爱糖果数字时间特效
2016/12/30 Javascript
jquery中绑定事件的异同
2017/02/28 Javascript
详解升级react-router 4 踩坑指南
2017/08/14 Javascript
element-ui 上传图片后清空图片显示的实例
2018/09/04 Javascript
layer设置maxWidth及maxHeight解决方案
2019/07/26 Javascript
JavaScript Reflect Metadata实现详解
2019/12/12 Javascript
[06:53]2018DOTA2国际邀请赛寻真——为复仇而来的Newbee
2018/08/15 DOTA
简单解析Django框架中的表单验证
2015/07/17 Python
在Django的session中使用User对象的方法
2015/07/23 Python
对python 多个分隔符split 的实例详解
2018/12/20 Python
Django前后端分离csrf token获取方式
2020/12/25 Python
详解使用python爬取抖音app视频(appium可以操控手机)
2021/01/26 Python
canvas简易绘图的实现(海绵宝宝篇)
2018/07/04 HTML / CSS
美国香薰蜡烛品牌:PADDYWAX
2018/10/06 全球购物
后勤人员自我鉴定
2013/10/20 职场文书
研究生自我鉴定范文
2013/10/30 职场文书
教育学专业毕业生的自我鉴定
2013/11/26 职场文书
个人授权委托书
2014/04/03 职场文书
学生请假条
2014/04/11 职场文书
纠纷协议书
2014/04/16 职场文书
2014年科室工作总结
2014/11/20 职场文书
汽车转让协议书
2015/01/29 职场文书
安全员岗位职责
2015/02/10 职场文书
综合办公室岗位职责
2015/04/11 职场文书
2015年远程教育工作总结
2015/05/20 职场文书
使用HTML+Css+transform实现3D导航栏的示例代码
2021/03/31 HTML / CSS