業務中遇到這種場景,咱們的業務嵌入別的系統中使用,系統採用Iframe調用咱們的業務,在使用過程當中主要遇到兩個問題:javascript
1。子頁面高度發生變化時外部的Iframe高度自適應的問題。html
2。子頁面不一樣獲取外部scrollTop的問題。java
這兩個問題其實均可以說是跨域通訊的問題。跨域
這兩個問題咱們採用了不一樣不一樣的方案來解決。瀏覽器
1。子頁面高度發生變化時外部的Iframe高度自適應的問題。post
咱們採用在外部系統中增長一個代理頁面,這樣的話這個代理頁面就和外部系統處於同一個域中了,至關於咱們在外部系統中安插了一個內鬼,使用這個代理頁面來調整外部Iframe的高度。ui
代碼實現spa
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方法的邏輯較簡單code
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 ,使之獲取滾動條的高度後在發消息給子頁面。各有優劣吧。