Jquery load 方法下前进、后退、刷新问题的解决
做一个后台管理系统的时候,用到了admin-lte框架。不过其实大部分后台管理系统都是这样的设计,即,左边是可以缩进的菜单栏,右边是内容,用户点击菜单的时候,菜单栏和上边的用户信息栏并不会重新加载,也就是不会跳转到新的页面,仅仅是更新了右边的内容模块。
然而这种实现方式有一种缺陷:当用户点击前进按钮、后退按钮、刷新按钮时,由于实际上用户只访问了一个页面,其他的“功能页面”都是更新此页面中的main-content
的内容,所以,前进、后退、刷新时,可能会退出当前网站、页面,这并不是我们在访问普通网页时期望的前进、后退、刷新行为。然而这种实现方式有一种缺陷:当用户点击前进按钮、后退按钮、刷新按钮时,由于实际上用户只访问了一个页面,其他的“功能页面”都是更新此页面中的main-content
的内容,所以,前进、后退、刷新时,可能会退出当前网站、页面,这并不是我们在访问普通网页时期望的前进、后退、刷新行为。
跟大多数人一样,我使用的是jquery
的load()
方法,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <li><a href="javascript:loadMenu('<%=request.getContextPath()%>/commons/redirect.do?path=management/user_list')">用户列表</a></li>
<li><a href="javascript:loadMenu('<%=request.getContextPath()%>/commons/redirect.do?path=management/department_list')"></i>归属部门</a></li> ... <script> function loadMenu(path, parameter) { $('#main-content').load(path, parameter); }
$(function () { var defaultPath = '<%=request.getContextPath()%>/commons/redirect.do?path=task/task_list'; loadMenu(defaultPath); }); </script>
|
上述的代码中,定义了一个loadMenu方法,按钮点击的时候调用此方法,将新的内容页面加载到main-content
这个<div>
块中,实现了菜单栏不刷新、内容变化的功能。当第一次进入此页面时,自动调用loadMenu方法,加载默认页面。
然而这种实现方式有一种缺陷:当用户点击前进按钮、后退按钮、刷新按钮时,由于实际上用户只访问了一个页面,其他的“功能页面”都是更新此页面中的main-content
的内容,所以,前进、后退、刷新时,可能会退出当前网站、页面,这并不是我们在访问普通网页时期望的前进、后退、刷新行为。
下面提出一种解决方案,实测有效:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| ... <script>
$(function () { $.refresh() })
function loadMenu(path, parameter) { $.pushState(path, parameter) $.loadPage(path, parameter) }
$.extend( { loadPage: function (url, data) { console.log('loading url: ' + url) $('#main-content').load(url, data); }, pushState: function (url, data) { console.log("pushing state: " + url) history.pushState({urlStr: url, data: data}, "页面标题", "?_url=" + url); },
popState: function () { window.addEventListener("popstate", function () { var currentState = history.state if (currentState != null) { var url = ".." + currentState.urlStr console.log('poping state: ' + url) $.loadPage(url, currentState.data) } }) },
refresh: function () { var currentState = history.state; if (currentState != null) { var loadUrl = ".." + currentState.urlStr console.log('refreshing state: ' + loadUrl) $.loadPage(loadUrl, currentState.date) }else{ var defaultPath = '<%=request.getContextPath()%>/commons/redirect.do?path=task/task_list'; loadMenu(defaultPath) } } } )
$.popState() </script>
|
如上述代码,我们拓展了popState/refresh方法,当用户点击前进(后退)、刷新按钮时会分别触发这两个方法, 然后在方法中获取到用户(这里指我…)期望的路径,通过load
方法将这些内容加载。
那么这些“记录”是如何保存和获取的呢?当用户点击菜单(按钮),调用loadMenu
方法时,我们先调用pushState方法,将他要访问的页面添加到历史记录history.pushState
,然后在前进、后退、刷新时获取到对应的历史记录history.state
,通过load方法加载这些内容饥渴。并且参数也可以通过对应data字段保存和获取。
实测有效,不过还需要考虑,加载页面后菜单栏的active
问题。可以通过传递的参数来判断,修改className,这里不赘述。