业务中遇到这种场景,我们的业务嵌入别的系统中使用,系统采用Iframe调用我们的业务,在使用过程中主要遇到两个问题:
1。子页面高度发生变化时外部的Iframe高度自适应的问题。
2。子页面不同获取外部scrollTop的问题。
这两个问题其实都可以说是跨域通信的问题。
这两个问题我们采用了不同不同的方案来解决。
1。子页面高度发生变化时外部的Iframe高度自适应的问题。
我们采用在外部系统中增加一个代理页面,这样的话这个代理页面就和外部系统处于同一个域中了,相当于我们在外部系统中安插了一个内鬼,使用这个代理页面来调整外部Iframe的高度。
代码实现
window.setInterval("proxyHeight()", 400);//每隔400毫秒监听下页面高度(其实就是我们子页面的高度) var pageHeightPre = 0; function proxyHeight() { var proxyUrl = Rose.browser.getParameter(‘proxyUrl‘);//获取代理页面的URL if (proxyUrl != null){ var height = document.documentElement.scrollHeight; if(Rose.browser.ie){ height = document.body.scrollHeight; } if(height <= 0) { return; } if (height < 450) { height = 450; } if(height != 0 && pageHeightPre != height){ pageHeightPre = height; document.getElementById(‘proxyFarme‘).src= proxyUrl +‘?proxyHeight=‘+height; } } }
代理页面的代码大致是这样的
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="./js/common/Rose/1.0.0/Rose.src.js"></script> </head> <body> </body> </html> <script type="text/javascript" > window.onload = function(){ var proxyHeight = Rose.browser.getParameter(‘proxyHeight‘); if(proxyHeight != null){ parent.parent.reinitIframe(proxyHeight);//调用系统的reinitIframe方法
} } </script>
reinitIframe方法的逻辑较简单
function reinitIframe(height) { var iframe = $(".ui-navtab-iframe:visible").find("iframe"); $(iframe).height(height); }
这种方式也能满足我们业务需要。
2。子页面不同获取外部scrollTop的问题,这个问题我们采用postMessage的方式。
在外部系统中我们监听滚动条的事件
$(window).scroll(function(event){ var iframe = $(".ui-navtab-iframe:visible").find("iframe"); if(iframe.length == 0){ return; } var scrollHeight = $(document).scrollTop() scrollHeight = JSON.stringify({‘scrollHeight‘: scrollHeight}); iframe[0].contentWindow.postMessage(scrollHeight, "*"); });
在子业务中接受消息
function receiveMessage(e){ if (e != null && e != undefined && e.data != undefined ){ if(typeof(e.data) == "string"){ try{ var data = JSON.parse(e.data); if(data.scrollHeight != null && data.scrollHeight != undefined){ window.iframScrollHeight = data.scrollHeight; } }catch(e){ } } } } attachEventListener("message",receiveMessage); function attachEventListener(type, listener){ if(window.addEventListener){ // 兼容所有浏览器除了ie9以下 window.addEventListener(type, listener, false); }else if(window.attachEvent){ // 兼容ie9以下浏览器 window.attachEvent("on"+type, listener); } }
这样的话只要外部的滚动条有变化就会发送滚动条目前高度的消息,子页面接收到消息后 就能获取到外部的滚动条的高度了,也能满足业务需要。
美中不足的是目前的写法是实时监听,不过也可以修改为子页面发送消息给外部Iframe ,使之获取滚动条的高度后在发消息给子页面。各有优劣吧。
时间: 2024-11-07 02:02:24