版本一
思路是在頁面中指定位置預留一個js鉤子, 然後在頁面載入完成後向後端發送ajax請求, 判斷使用者是否登入, 並寫到鉤子裡相應文本. 於是版本一產生了...
代碼如下 |
複製代碼 |
(function($){ var user = window.user = {}; // 使用者資料 user.data = {}; // 使用者狀態, 0未登入, 非0則視為已登入, 可擴充為使用者等級 user.status = 0; /** * 初始化 * @return {object} user對象 */ user.init = function(){ //負責從後端ajax請求使用者是否登入, 如果已登入則返回使用者相關資訊, 否則視為未登入 //請求完成後改變使用者的status狀態, 並把使用者資訊寫入到user.data上 $.get("後端url", function(res){ if(res.error === 0){//傳回值同後端協定 user.status = 1; user.data.userName = res.data.userName;//類比使用者名稱 } else { user.status = 0; user.data = {}; } //渲染狀態到頁面 user._renderHTML(); }, 'json'); //類比惰性方法以防止頁面多次使用 user.init = function(){ return user; } return user; } /** * 使用者登入 * @param {Function} callback 回調 * @return {object} user對象 */ user.login = function(callback){ if("function" === typeof callback){ if(user.status !== 0){//如果使用者已登入則直接運行回調, 參數為使用者資料 callback.call(user, user.data); } else { //未登入時彈出使用者登入層,讓其登入, 登入完成後重新整理當前頁面, 當然也可以像 youku 一樣不重新整理頁面, 但要做的工作非常多, 這裡不解釋 } } return user; } /** * 渲染使用者狀態到頁面, 當前為類比用 */ user._renderHTML = function(){ var html;
if(user.status !== 0){//已登入 html = '您好 '+ user.data.userName +' , <a href="#">退出</a>'; } else { html = '請先登入<a href="#">登入</a>'; } $("#J_bar_html").html(html); } }(jQuery)); 頁面中可以這麼幹: <a href="javascript:;" id="J_set_fav">點擊收藏</a> <script type="text/javascript"> user.init();//初始化使用者 $("#J_set_fav").on("click", function(){ user.login(function(){//回調必須是登入狀態下使用, 如果沒有登入會執行畫出登入框讓使用者登入 alert("正在收藏"); }); }); </script> |
版本二
於是頁面中可能需要判斷使用者是否登入, 還有退出登入, 在版本一的基礎上添加 檢查和退出方法, 但這些退出和檢查只是依據後端的傳回值, 且退出只是前端靜態退出, 當然你也可以向後端發送ajax
代碼如下 |
複製代碼 |
/** * 前端退出 * @return {object} user對象 */ user.exit = function(){ user.status = 0; user.data = {}; user._renderHTML();//重設下頁面狀態 return user; } /** * 檢查使用者是否已經登入 * @return {boolean} true為登入, false為未登入 */ user.check = function(){ return user.status !== 0; } |
經過以上代碼後前端的登入退出就基本完成了, 但由於每次都要請求後端, 而這個請求是非同步, 如果返迴響應時間過長, 那麼在這個時間段使用 user.login, user.check 是不正確的, 因為是在ajax完成後才能正確的設定使用者的登入狀態, 這也好比domReady事件一樣, dom樹都沒有建立成功就使用dom對象了, 就報錯了啊... 於是她有domReady, 咱有userReady...於是版本三產生了...
版本三
在版本二的基礎上添加 ready 事件, 確保必須在使用者初始完成後才執行代碼...
代碼如下 |
複製代碼 |
var isReady = false,//使用者是否初始完畢 readyList = [];//初始化回調列表 /** * 渲染使用者狀態到頁面, 當前為類比用 */ user._renderHTML = function(){ // ... runList();//因為已經渲染完頁面了, 可以執行ready回調事件了 } /** * 使用者ready事件 * @param {Function} callback 初始完成後回調 * @return {object} user對象 */ user.ready = function(callback){ if("function" === typeof(callback)){ if(isReady){//如果已經初始完畢 callback.call(user, user.data); } else {//沒有的話則追加到回調列表 readyList.push({ callback: callback }); } } return user; } /** * 執行回調事件 */ function runList (){ var i = 0, len = readyList.length; if(len > 0){ for(;i<len;i++){ readyList.callback && readyList.callback.call(user, user.data); } } isReady = true;//設定為已經初始完畢 readyList.length = 0;//重設回調 runList = $.noop;//惰性方法 } |
這樣來使用以確保必須在使用者判斷結束後才綁定事件, 從而解決誤判斷帶來的使用者體驗丟失:
代碼如下 |
複製代碼 |
<a href="javascript:;" id="J_set_fav">點擊收藏</a> <script type="text/javascript"> user.init();//初始化使用者 user.ready(function(){ if(user.check()){alert("已登入");} else {alert("未登入");} $("#J_set_fav").on("click", function(){ user.login(function(){//回調必須是登入狀態下使用, 如果沒有登入會執行畫出登入框讓使用者登入 alert("正在收藏"); }); }); }); </script>
|
整個前端登入, 退出大概架構就是這樣了, 當然還可以對接第三方登入, 註冊等方法. 還可以擴充出一些使用者相關的操作, 如: 收藏啊, 添加關注啊等等.
注: 只是代碼思路, 具體代碼可最佳化, 可精簡, 且跟據實際情況訂製不同的功能.