实现方案1:location.hash传值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现方案1:location.hash传值相关的知识,希望对你有一定的参考价值。
实现方案1:location.hash传值
父页面:parent.html(所在域:www.parent.com)
子页面:child.html(所在域:www.child.com)
要实现父子页面双向的事件调用和传值,需要多加一个代理页面,主要用于子页面调用父页面的方法
代理页面:proxy.html(所在域:www.parent.com)必须与父页面在同域下
父页面调用子页面方法(即事件通过父页面发起,在子页面中执行):
父页面中直接设置iframe的src中的hash值
parent.html:
1
2
|
var frameurl = "http://www.child.com/child.html" document.getElementById( "frameId" ).src=frameurl+ "#action=" +actionName+ "&data=" +dataJSONStr; |
子页面中设置定时器监听hash的变化,监听到后直接执行该方法
child.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
var currentHash = location.hash; setInterval( function (){ var hash = location.hash.substring(1); if (currentHash!==hash){ var action = ...; var data = ...; childFuncClass[action](data); } },1); |
同样可以使用onhashchange事件监听到
子页面调用父页面方法(事件通过子页面发起,在父页面中执行)
在子页面child.html中添加一个iframe链接到上面所说的proxy.html,child.html中通过改变proxy.html的hash值,在proxy.html中监听hash变化事件,监听到以后直接调用parent.html中的方法(与父页面调用子页面方法一致)
proxy.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
var currentHash = location.hash; setInterval( function (){ var hash = location.hash.substring(1); if (currentHash!==hash){ var action = ...; var data = ...; window.parent.parent[action](data); } },1); |
存在问题:
data长度限制,在chrome,ff,safari等浏览器中hash长度限制有50K以上,但是在ie下最多2000左右的限制。
回调函数的处理
通常情况下父页面在调用子页面的方法时会有一些回调函数(函数是在parent.html中编写和执行,但是需要child.html中的方法执行完成后再执行,有些情况下会需要child.html中执行的结果)
比如(通常情况下会做接口的封装):
parent.html:
1
2
3
4
5
6
7
|
var data={.....}; childFunc.func1(data, function (result){ //result即为child.html中执行func1后的结果值 }); |
child.html:
1
2
3
4
5
6
7
8
9
|
var func1 = function (data,callback){ //对data的一些操作 var result = ...; callback&&callback(result); } |
如果出现这种情况的话parent.html中定义的匿名回调函数是不可能以字符串的形式传递到child.html中去的,并且也无法在child.html中再去执行父页面的回调函数
解决方法:
在接口封装的时候将回调函数保存下来,通过一个唯一的函数名传递到child.html中,child.html中的方法执行完成后将该函数名传递到proxy.html中执行该函数
以上面的func1为例
parent.html:
1
2
3
4
5
6
7
8
|
var eventIndex=0; childFunc.func1 = function (data,callback){ if ( //callback是function类型){ //此时window是parent页面的对象 window[ "myEvent" +eventIndex] = callback;<br data-filtered= "filtered" > childIframe.hash= "action=...&data=...&callback=myEvent" +eventIndex;<br data-filtered= "filtered" > } }; |
child.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
var currentHash = location.hash; setInterval( function (){ var hash = location.hash.substring(1); if (currentHash!==hash){ var action = ...; var data = ...; var callback=....; //应该是myEvent+index childFuncClass[action](data, function (result){ proxyIfram.src.hash= "action=" +callback+ "&data=" +result; }); } },1); |
proxy.html:
1
2
3
4
5
6
7
8
9
10
|
setInterval( function (){ if ( //hash changed){ var callback = //hash.callback var callbackData = //hash.callbackData window.parent.parent[callback](callbackData); } },1); |
实现方案2:window.postMessage方法
由于方案1中对ie兼容性有问题(所有ie版本,包括ie11和edge都存在这个问题),方案2使用postMessage方法,该方法理论上对数据量没有限制(猜的),并且对ie可用
同样是使用iframe嵌入,
parent.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171208685.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171208565.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171208433.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171208291.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171208151.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171208027.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171207909.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170579603.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170579335.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170579081.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170578815.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170578589.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170578353.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170578089.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170577859.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170577615.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170577343.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170577101.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170576861.html
http://www.cntrades.com/b2b/yase888/sell/itemid-170576625.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171211333.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171211207.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171211091.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171210937.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171210789.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171210609.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171210443.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171210319.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171210199.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171210015.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171209849.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171209717.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171209589.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171209455.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171209335.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171209221.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171209129.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171209031.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171208919.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171208817.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171221799.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171221681.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171221585.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171221479.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171221391.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171221293.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171221191.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171221111.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171213097.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171212975.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171212831.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171212651.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171212521.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171212377.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171212237.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171212099.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171211945.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171211771.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171211621.html
http://www.cntrades.com/b2b/yase888/sell/itemid-171211477.html
1
2
3
4
|
var iframe = document.getElementById( "childFrame" ).contentWindow; var msg = {data:parentData,action:childFunc,callback: /*类似于上面的方法myEventIndex*/ } var childDomain = "http://www.child.com" iframe.postMessage(msg,childDomain); |
1
2
3
4
5
6
|
window.addEventListener( "message" , function (obj){ var data = obj.data; var action = data.action; var data = data.data; parentFuncClass[action](data); }); |
1
|
<br data-filtered= "filtered" > |
child.html
1
2
3
4
5
6
7
8
9
10
11
|
window.addEventListener( "message" , function (obj){ var data = obj.data; var action = data.action; var data = data.data; var callback = data.callback; childFuncClass[action](data, function (result){ var d = {action:callback,data:result}; var parentDomain= "http://www.parent.com" ; window.parent.postMessage(d,parentDomain); }); }); |
真的是坑啊,把方案1中的坑都走过后才找到方案2的方法
以上是关于实现方案1:location.hash传值的主要内容,如果未能解决你的问题,请参考以下文章
Chrome:调试谁更改了 document.location.hash
window.location.hash 和 location.hash 有啥区别? [复制]