單頁站點優劣
傳輸數據少
服務可不中斷
前后端開發更規范
首次加載數據大耗時長
極差的SEO(搜索引擎優化)
導航需要人為處理
單頁應用的實現方式
iframe
ajax+div+historyapi
基於iframe制作單頁博客
1 $('a[target="contentFrame"]').click(function(){ 2 var $this = $(this), 3 url = $this.attr('href'), 4 mainHost = location.host, 5 i = url.indexOf(mainHost); 6 $active.removeClass('active'); 7 $active = $this.parent('li'); 8 $active.addClass('active'); 9 if(i !== -1){ 10 url = url.substr(i + mainHost.length); 11 } 12 window.location.hash = '#' + url; 13 return false; 14 });
在iframe頁面(子頁面)中,也有一段類似的js,為iframe中的頁面超鏈接綁定事件
1 $('a').click(function(){ 2 var url = $(this).attr('href') 3 if(url && url != '#' && url.indexOf('http') == 0){ 4 var mainHost = window.parent.location.host, 5 i = url.indexOf(mainHost); 6 if(i !== -1){ 7 url = url.substr(i + mainHost.length); 8 } 9 window.parent.location.hash = '#' + url; 10 } 11 return false; 12 });
注意這兩段代碼,修改的都是父文檔(頂層窗口)地址欄的hash值。所以,只需要在父文檔中監聽onhashchange事件,在事件響應中設置iframe的src 進而load子頁面。
1 $container = $('div.page-body > iframe'); 2 window.onhashchange = function(){ 3 $container.attr('src',location.hash.substring(1)); 4 };
iframe高度不能根據內容自適應,需要在子頁面load之后刷新iframe的高度
1 var refreshHeight = function(){ 2 var $this = $container, 3 minHeight = $('.page-right').height() - $('.top-menu').height() - 20, 4 contentHeight = $this.contents().find('body').height() + 10; 5 $this.height(contentHeight < minHeight ? minHeight : contentHeight); 6 }; 7 8 $container.load(function(){ 9 refreshHeight(); 10 }); 11 // 首次刷新,否則加載過程中會看到白框 12 refreshHeight();
到這里基本已經實現任意跳轉、回退、前進頁面不再刷新整個頁面。下面的代碼是為了解決當打開多個頂層文檔時(開多個窗口),音樂不重復播放,方法也很簡單,在localStorage中記錄頂層文檔的數量,每開一個新窗口加1,關閉時減1,只要記錄數大於1便不自動播放。
1 if(window.localStorage){ 2 var $window = $(window); 3 $window.on('beforeunload',function(){ 4 console.log('-1'); 5 localStorage.framePage = localStorage.framePage - 1; 6 }); 7 8 window.addEventListener("storage", function(e){ 9 console.log("oldValue: "+ e.oldValue + " newValue:" + e.newValue) 10 }); 11 } 12 var autoplay = location.host !== 'movesun.qq.com'; 13 if(window.localStorage){ 14 if(Number(localStorage.framePage) >= 1){ 15 autoplay = false; 16 } 17 18 if(isNaN(localStorage.framePage) || Number(localStorage.framePage) <= 0) localStorage.framePage = 1; 19 else { 20 localStorage.framePage = Number(localStorage.framePage) + 1; 21 } 22 }
博客依然有兩個問題需要解決
1、目前的瀏覽器已經支持記錄iframe變更的歷史記錄,通過hash記錄歷史就顯的沒有必要了。目前網站每次跳轉實際產生了兩條歷史記錄。后面找時間移出hash記錄或者禁用iframe歷史記錄

2、考慮到搜索引擎收錄的超鏈接應該是非hash模式的url,比如用戶看到的是movesun.com/#/blog/list ,而實際收錄的卻是movesun.com/blog/list,通過site:movesun.com指令搜索也可以看到

直接訪問這類url地址,將直接打開iframe里的內容,所以,當用戶直接點擊搜索引擎的結果進入博客時,應該將用戶跳轉到hash模式,頁面才能正常顯示,但這樣對搜索引擎而言,會陷入一個無限循環,影響搜索引擎收錄。
前端因直接面向用戶,使得技術也更新迭代的頻繁,前端開發人員也需要不斷學習以追趕時代的潮流。而反觀后台技術,十年來都沒什么及其巨大的變化,很多技術經久不衰,后端開發完全有一招鮮吃遍天的架勢。這也是的前端人員比較搶手,在一些公司都存在前端與后台人力嚴重不平衡的現像,十幾位后台搭配一位前端的事情,也不是沒有,奇貨可居,優秀的前端是非常吃香的。
