我有一个单页应用程序。所有数据都由ajax检索并呈现在客户端上。我有下一个工作流程:
- 用户打开项目列表。列表具有无限滚动
- 用户滚动并单击项目
- 系统发出ajax请求,生成新的html并替换以前的内容
- 用户单击浏览器的后退按钮
- 系统更改url(historyjs),路由器加载项目并呈现列表。但是卷轴的位置丢失了!所以用户需要滚动到列表上的上一个位置
如何在上一步/下一步行动中保持这一地位,并为所有项目实施通用解决方案?
返回浏览器按钮通常会返回到"缓存"页面。如果未缓存,则它将重新呈现页面。显然,考虑到HTTP的性质,状态是丢失的。我的建议是将项目的编号存储在列表中,或将项目值存储在"Session"变量或"Cache"对象中,并在页面加载之前从那里访问它。
如果会话["lastSelectedItem"]!=null,然后获取值/数字,并使用jQuery或其他方法将"Selector"设置在正确的位置。
只需添加到列表id并滚动到此id
<div id="item_1002">content of 1002</div>
<div id="item_1003">content of 1003</div>
<div id="item_1004">
<span>content of 1004</span>
<a href="#item_1002">goto 1002</a>
</div>
这将工作甚至两js:)
用户点击链接,使用id
(如果在当前页面上可用)发帖,并具有类似http://site.com/#item_1002
的位置。当用户点击返回浏览器时,将url更改为http://site.com/#item_1004
并滚动至<div id="item_1004">...
编辑
我确信这不起作用,但正如概念一样,它比我糟糕的英语要好
<script type="text/javascript">
// scroll to id
// http://stackoverflow.com/questions/68165/javascript-to-scroll-long-page-to-div
// need to use this
// History.Adapter.bind(element,event,callback);
// but I'm stuck how it works
// so jQ
$(document).ready(function(){
$('a').click(function(){
// document.getElementById('youridhere').scrollIntoView();
$(this).scrollIntoView();
History.pushState({}, 'title', '#item_ID');
})
// Bind to StateChange Event
// Note: We are using statechange instead of popstate
History.Adapter.bind(window,'statechange',function(){
// Note: We are using History.getState() instead of event.state
var State = History.getState();
$(State.url).scrollIntoView();
});
})
</script>
<div id="item_1002">content of 1002</div>
<div id="item_1003">content of 1003</div>
<div id="item_1004">
<span>content of 1004</span>
<a href="javascript:">goto 1002</a>
</div>
这是我的解决方案(coffeescript):
class window.Explore
cached_pages = {}
preserve: (url)=>
current_position = window.pageYOffset || document.documentElement.scollTop || 0
cached_pages[url] =
position: current_position
clean: =>
cached_pages = {}
scroll_back: (url)=>
if cached_pages[url]
$('body').scrollTop cached_pages[url].position
window.cached_explore = new Explore()
window.prev_state = undefined
window.current_state = undefined
$ ->
History = window.History
if !History.enabled
return false
History.Adapter.bind window, "statechange", =>
# store previous history state
window.prev_state = window.current_state
window.current_state = History.getState()
# preserve each page position before leaving
if window.prev_state and window.prev_state.hash
window.cached_explore.preserve(window.prev_state.hash)
place_match = location.pathname.match(//place/(.*)/)
# place page
if place_match
# retrieve place
window.retrieve_place place_match[1], window.search_query, (err, place_dto) ->
# render place page
window.show_place_popup place_dto
# explore places page
else if location.pathname is '' or location.pathname is '/'
# check if a page was already opened
window.renred_explore_page()
if window.prev_state
window.cached_explore.scroll_back location.pathname
如果您不想或不能使用会话,请尝试使用History.replaceState()
。
如果用户在无限滚动中加载新的列表项目,请替换历史状态History.replaceState()
,并附加项目计数或最后一个项目ID。
如果用户单击后退按钮,评估项目计数,加载列表并向下滚动。