3

我有单页应用程序。所有数据都由 ajax 检索并在客户端呈现。我有下一个工作流程:

  1. 用户打开项目列表。列表有无限滚动
  2. 用户滚动并点击项目
  3. 系统发出ajax请求,生成新的html并替换之前的内容
  4. 用户点击浏览器的后退按钮
  5. 系统更改 url ( historyjs ) 和路由器加载项目并呈现列表。但是滚动的位置丢失了!所以用户需要滚动到列表中的上一个位置。

如何在后退/下一个行动中保持这个位置并为所有项目实施通用解决方案?

4

4 回答 4

1

这是我的解决方案(咖啡脚本):

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
于 2012-07-20T13:30:50.123 回答
1

返回浏览器按钮会更频繁地将您返回到“缓存”页面。如果没有缓存,那么它将重新渲染页面。显然,由于 HTTP 状态的性质是丢失的。我的建议是将项目的编号存储在列表中,或者将项目值存储在“会话”变量或“缓存”对象中,并在页面加载之前从那里访问它。

如果 Session["lastSelectedItem"] != null,则获取值/数字,并使用 jQuery 或其他方法在正确的位置设置“选择器”。

于 2012-07-19T11:45:15.900 回答
1

只需添加到列表 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>

这甚至可以工作 wo 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>
于 2012-07-19T12:02:25.050 回答
0

如果您不想或无法使用会话,请尝试使用History.replaceState().

如果用户在无限滚动中加载新列表项,请替换历史状态History.replaceState()并附加项目计数或最后一个项目 ID。

如果用户单击后退按钮,则评估项目计数,加载列表并向下滚动。

于 2012-07-19T11:59:22.363 回答