iframe 通信和跨域通信

几年前页面里使用iframe嵌套使用的还是很多的。

以下是多种使用方法:

1、同域下嵌套:

父页面:

<iframe src="iframe2.html" id="iframe2" name="iframe2"></iframe>
window.οnlοad=function(){
				//父页面修改iframe
				var docu=document.querySelector('#iframe2');
				docu.contentWindow.document.querySelector('#div1').innerHTML='div1'
				
				//根据name调用
				//iframe2.window.document.getElementById('div1').innerHTML='update'
				
				//调用子方法
				docu.contentWindow.child();
			}
			function fu(){
				console.log('父方法')
			}

子页面:

<div id="div1"></div>
		<script>
			//子改父用parent.document
			window.parent.document.querySelector('#iframe2').style.backgroundColor='#ccc'
			//window.parnet.fun 调用父方法
			window.parent.fu();
			function child(){
				console.log('子方法')
			}
		</script>

父页面调用子页面:

iframename.window.document.XX

iframename.window.function

idel.contentWindow.document.XX

idel.contentWindow.function

子调用父页面:

parent.document.XX

parent.function

2、跨域下hash传递值:

在页面如果只是修改了url的标签符页面是不会刷新的。

但会触发hashChange方法

可以利用这个来实现双方通信

父页面:

<input type="text" id="id_name">
		<iframe id="iframe1" src="http://localhost:8032/2015_project/html5/iframe3.html">
			
		</iframe>
		<script >
			var url='http://localhost:8032/2015_project/html5/iframe3.html'
			//监听hash 变动
			//获取子修改了的url上的hash实现传递值
			window.addEventListener('hashchange',function(e){
				var m=location.hash;
				console.log(m);
				document.querySelector('#id_name').value=m.substr(1)
			})
			window.οnlοad=function(){
				//获取iframe修改其url的hash
				var iframe1=document.querySelector('#iframe1');
				iframe1.contentWindow.location.href=url+'#name_xiaoyun'
			}
		</script>

子页面:

<button id="but1">修改hash传递值</button>
		<script>
			var url='http://127.0.0.1:8020/2015_project/html5/iframebody2.html';
			//监听hash修改
			window.addEventListener('hashchange',function(){
				var m=location.hash;
				console.log(m);
			})
			var but1=document.querySelector('#but1');
			but1.addEventListener('click',function(){
				window.parent.location.href=url+'#name_star'
			})
		</script>
父和子页面绑定onhashChange

通过location.hash来获取#XX

父页面修改url

idel.contentWindow.location.href='XX#XX'

子页面修改url

window.parent.location.href='Xx#xx'


3、子页面单方面传递值到父通过window.name 或#has

window.name属性它不论同源,只要在同一窗口,前页面修改了name,后加载的页面是可以访问到的。

可以利用这点在b.com页面下设置name然后跳转到a.com b的页面。

此页面获取到name再调用父页面也就是a.com a的方法了。

或者a页面监听firame的Load事件然后获取name

其实b.com页面可以通过url把值传递给a.com b。

b收到后因为是同源所以可以调用父方法和el把值传递。

a.com a:

<iframe id="iframe1" src="http://localhost:8032/2015_project/html5/iframe4.html">
			
		</iframe>
		
		<script >
			var iframe1=document.querySelector('#iframe1');
			iframe1.οnlοad=function(){
				var name=iframe1.contentWindow.name;
				console.log(name)
			}
			function fn(name){
				console.log('父方法',name)
			}
		</script>

b.com 

<button id="but1">传递值</button>
		<script>
			var url='http://127.0.0.1:8020/2015_project/html5/iframe5.html';
			var but1=document.querySelector('#but1');
			but1.addEventListener('click',function(){
				window.name="name=star";
				location.href=url+'#hashname';
			})
			window.οnlοad=function(){
				console.log(window.name)
			}
		</script>

a.com b:

<script>
			window.οnlοad=function(){
				console.log(window.name)
				console.log(location.hash)
				window.parent.fn(location.hash)
			}
		</script>


以上这些取巧的方法以前是经常用的。

现在有了html5,有了新的办法:

4、postMessage

为window增加了postMessage(),允许跨域通信

其参数1:发送的内容,参数2是接收消息的窗口的源,也就是url,当然也可以用*.向所有窗口发送

子窗口向父窗口也类似:

opener.postMessage('xx','url')

opener 属性返回创建此窗口的window对象引用

父子窗口通过监听message来获取值

event.source 发送消息窗口

event.origin:消息发向的窗口

event.data消息内容

source 可判断发送源url,进行过滤

父页面:

<div style="width:200px; float:left; margin-right:200px;border:solid 1px #333;">
          <div id="color">Frame Color</div>
     </div>
     <div>
         <iframe id="child" src="http://localhost:8038/html5/message2.html"></iframe>
     </div>
 
     <script type="text/javascript">
 
         window.οnlοad=function(){
         	//postmessage(参数,子页面域名)
         	document.querySelector("#child").contentWindow.postMessage('getcolor','http://localhost:8038');
         }
 			
         window.addEventListener('message',function(e){
         	console.log(e);
             var color=e.data;
             document.getElementById('color').style.backgroundColor=color;
         },false);
     </script>

子页面:

<div id="container" οnclick="changeColor();" style="widht:100%; height:100%; background-color:rgb(204, 102, 0);">
             click to change color
         </div>
         <script type="text/javascript">
             var container=document.getElementById('container');
 
             window.addEventListener('message',function(e){
                    console.log(e);
                 if(e.source!=window.parent) return;
                 var color=container.style.backgroundColor;
                 window.parent.postMessage(color,'*');
             },false);
 
             function changeColor () {            
                 var color=container.style.backgroundColor;
                 if(color=='rgb(204, 102, 0)'){
                     color='rgb(204, 204, 0)';
                 }else{
                     color='rgb(204,102,0)';
                 }
                 container.style.backgroundColor=color;
                 window.parent.postMessage(color,'*');
             }
         </script>


还有一种跨域写法:

a.com 上的a页面嵌套了b.com 上的b页面。b需要和a通信。

b页面上又嵌套 了a.com 上的c页面。

b页面不直接和a页面通信,b修改c url 的hash。

c监听onhashChange获取值。

由c和a页面通信,因为c和a是在同域下的。

c可以用parent.parent.fn() 来向a传递值。

因为是三层嵌套所以要两次parent.


通过iframe实现post 提交。

以前在post提交时form 时不想跳转页面,就有一利用target 提交到iframe

iframe来接收信息。

如果想父页面知道接收信息,可以在服务器返回时输出script 

window.parent.fn(xx) 调用父级方法把信息传递。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值