国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

location.hash保存頁(yè)面狀態(tài)的技巧

2019-11-20 10:11:44
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

hash 屬性是一個(gè)可讀可寫的字符串,該字符串是 URL 的錨部分(從 # 號(hào)開(kāi)始的部分)。

語(yǔ)法

location.hash

在我們的項(xiàng)目中,有大量ajax查詢表單+結(jié)果列表的頁(yè)面,由于查詢結(jié)果是ajax返回的,當(dāng)用戶點(diǎn)擊列表的某一項(xiàng)進(jìn)入詳情頁(yè)之后,再點(diǎn)擊瀏覽器回退按鈕返回ajax查詢頁(yè)面,這時(shí)大家都知道查詢頁(yè)面的表單和結(jié)果都回到了默認(rèn)狀態(tài)。

如果每次返回頁(yè)面都要重新輸入查詢條件,或有甚者還得轉(zhuǎn)到列表的第幾頁(yè),那這種體驗(yàn)用戶真的要抓狂了。

在我們的項(xiàng)目中,寫了一個(gè)很簡(jiǎn)單的JavaScript基類來(lái)處理location.hash從而保存頁(yè)面狀態(tài),今天在此就分享給大家。

(本文的內(nèi)容可能對(duì)于JavaScript初學(xué)者來(lái)講有點(diǎn)難度,因?yàn)樯婕暗絁S面向?qū)ο蟮闹R(shí),如定義類、繼承、虛方法、反射等)

先看看我們的需求

我們的項(xiàng)目是一個(gè)基于微信的H5任務(wù)管理系統(tǒng),要完成的頁(yè)面原型如下圖所示:

需求應(yīng)該都很清晰,就是點(diǎn)擊查詢表單,用ajax返回查詢結(jié)果,然后點(diǎn)擊列表中的某一個(gè)任務(wù)進(jìn)入任務(wù)詳情頁(yè)。由于管理員(項(xiàng)目經(jīng)理)通常會(huì)一次處理多個(gè)任務(wù),所以就會(huì)不斷在任務(wù)詳情頁(yè)跟查詢列表頁(yè)切換,這時(shí)如果按返回鍵不能保存查詢頁(yè)面狀態(tài)的話,那每次返回查詢頁(yè)面都要重新輸入查詢條件,這樣的體驗(yàn)肯定是不能忍受的。

所以,我們需要想辦法將頁(yè)面狀態(tài)保存下來(lái),以便用戶按回退鍵的時(shí)候,查詢條件和結(jié)果都還在。

解決思路

保存頁(yè)面狀態(tài)的思路有很多啦,但是我們覺(jué)得用location.hash應(yīng)該是最好的方法。

思路如下:

1.用戶輸入查詢條件并點(diǎn)擊確定后,我們將查詢條件序列化成一個(gè)字符串,并通過(guò)“#”將查詢條件加到url后面得到一個(gè)新的url,然后調(diào)用location.replace(新的url)修改瀏覽器地址欄中的地址。

2.當(dāng)用戶按回退鍵回退到查詢頁(yè)面時(shí),也可以說(shuō)是頁(yè)面加載時(shí),將location.hash反序列化成查詢條件,然后將查詢條件更新到查詢表單并執(zhí)行查詢即可。

思路很簡(jiǎn)單,關(guān)鍵的地方就是location.replace方法,這個(gè)方法不僅僅是修改瀏覽器中地址欄的url,更重要的是會(huì)在window.history中替換當(dāng)前頁(yè)面的記錄。如果不用location.replace方法,那么每次回退都會(huì)回退到上一個(gè)查詢條件。當(dāng)然,這樣的需求可能對(duì)某些項(xiàng)目還有用。

最終解決方案

如果本文只是分享上面的解決思路,那價(jià)值就不大了。本文的價(jià)值應(yīng)該是我們寫的那個(gè)雖然簡(jiǎn)單但是卻很強(qiáng)大的JavaScript類。

如果你看明白了上面的解決思路,那就看看這個(gè)簡(jiǎn)單的JavaScript類吧:

(function() {if (window.HashQuery) {return;}window.HashQuery = function() {};HashQuery.prototype = {parseFromLocation: function() {if (location.hash === '' || location.hash.length === ) {return;}var properties = location.hash.substr().split('|');var index = ;for (var p in this) {if (!this.hasOwnProperty(p) || typeof this[p] != 'string') {continue;}if (index < properties.length) {this[p] = properties[index];if (this[p] === '-') {this[p] = '';}}index++;}},updateLocation: function() {var properties = [];for (var p in this) {if (!this.hasOwnProperty(p) || typeof this[p] != 'string') {continue;}var value = this[p];properties.push(value === '' ? '-' : value);}var url = location.origin + location.pathname + location.search + "#" + properties.join('|');location.replace(url);}};})(); 

這個(gè)類只有2個(gè)方法,HashQuery.parseFromLocation() 方法從location.hash反序列化為HashQuery子類的實(shí)例,HashQuery.updateLocation() 方法將當(dāng)前HashQuery子類的實(shí)例序列化并更新到window.location。

可以看到HashQuery這個(gè)類沒(méi)有任何屬性,那是因?yàn)槲覀冎欢x了一個(gè)基類,類的屬性都在子類中進(jìn)行定義。這也是符合實(shí)際的,因?yàn)椴樵儣l件都只有在具體的頁(yè)面才知道有哪些屬性。

另外,請(qǐng)注意這里的序列化和反序列化。這里的序列化僅僅是利用JavaScript反射機(jī)制將實(shí)例的所有字符串屬性(按順序)的值用“|”分隔;而序列化則是將字符串用“|”分隔后,再利用反射更新到實(shí)例的屬性(按順序)。

如何使用HashQuery類

使用的時(shí)候就非常簡(jiǎn)單了。

第一步,定義一個(gè)子類,將需要用到的查詢條件都加到字符串屬性當(dāng)中,如我們的代碼:

(function() {window.TaskSearchHashQuery = function () {HashQuery.constructor.call(this);this.iterationId = '';this.assignedUserId = '';this.status = '';this.keyword = '';};TaskSearchHashQuery.constructor = TaskSearchHashQuery;TaskSearchHashQuery.prototype = new HashQuery();})(); 

第二步,在查詢頁(yè)面調(diào)用HashQuery.parseFromLocation() 和 HashQuery.updateLocation()方法即可。下面的代碼是我們完整的查詢頁(yè)面:

(function() {var urls = {list: "/app/task/list"};var hashQuery = null;var pager = null;$(document).ready(function () {hashQuery = new TaskSearchHashQuery();hashQuery.parseFromLocation();//在這里調(diào)用的哦,從location反序列化objectupdateFormByHashQuery();$("#btnSearch").click(function() {updateHashQueryByForm();hashQuery.updateLocation();//在這里調(diào)用的哦,將查詢條件序列化之后更新到location.hash$("#lblCount").html("加載中...");pager.reload();page.hideSearch();});pager = new ListPager("#listTasks", urls.list);pager.getPostData = function(index) {return "pageIndex=" + index + "&pageSize=" + "&projectId=" + page.projectId+ "&iterationId=" + hashQuery.iterationId+ "&assignedUserId=" + hashQuery.assignedUserId+ "&status=" + hashQuery.status+ "&keyword=" + hashQuery.keyword;};pager.onLoaded = function() {$("#lblCount").html("共 " + $("#hfPagerTotalCount").val() + " 個(gè)任務(wù)");$("#hfPagerTotalCount").remove();};pager.init();});function updateHashQueryByForm() {hashQuery.iterationId = $("#ddlIterations").val();hashQuery.assignedUserId = $("#ddlUsers").val();hashQuery.status = $("#ddlStatuses").val();hashQuery.keyword = $("#txtKeyword").val();};function updateFormByHashQuery() {$("#ddlIterations").val(hashQuery.iterationId);$("#ddlUsers").val(hashQuery.assignedUserId);$("#ddlStatuses").val(hashQuery.status);$("#txtKeyword").val(hashQuery.keyword);};})(); 

總結(jié)

這就是我們項(xiàng)目中使用location.hash來(lái)保存頁(yè)面狀態(tài)的全部知識(shí)了。不知道大家的WEB項(xiàng)目中是如何處理這樣的需求的呢?

以上內(nèi)容是小編給大家介紹的location.hash保存頁(yè)面狀態(tài)的技巧,希望對(duì)大家有所幫助!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 吉水县| 印江| 海伦市| 仪征市| 祁东县| 故城县| 丰县| 周至县| 峨边| 桂阳县| 渭南市| 紫阳县| 金平| 龙州县| 石门县| 全州县| 兴安县| 牙克石市| 东阳市| 独山县| 涿州市| 江陵县| 永年县| 仁布县| 武清区| 武夷山市| 青龙| 苍南县| 分宜县| 鲁山县| 天柱县| 凭祥市| 洛宁县| 汤原县| 大宁县| 通海县| 新晃| 专栏| 蓝山县| 金湖县| 禹州市|