3

シングルページアプリケーションがあります。すべてのデータはajaxによって取得され、クライアントにレンダリングされます。次のワークフローがあります:

  1. ユーザーがアイテムのリストを開きます。リストには無限スクロールがあります
  2. ユーザーがスクロールしてアイテムをクリックします
  3. システムはajaxリクエストを作成し、新しいhtmlを生成し、以前のコンテンツを置き換えます
  4. ユーザーがブラウザの戻るボタンをクリックする
  5. システムはURL(historyjs)を変更し、ルーターはアイテムをロードしてリストをレンダリングします。しかし、スクロールの位置は失われています!したがって、ユーザーはスクロールしてリストの前の位置に移動する必要があります。

バック/次のアクション中にこの位置を維持し、すべてのプロジェクトに一般的なソリューションを実装するにはどうすればよいですか?

4

4 に答える 4

1

これが私の解決策です(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
于 2012-07-20T13:30:50.123 に答える
1

ブラウザボタンに戻ると、「キャッシュ」ページに戻ることがよくあります。キャッシュされていない場合は、ページが再レンダリングされます。明らかに、HTTP状態の性質を考えると失われます。私の提案は、リスト内のアイテムの番号、またはアイテムの値を「Session」変数または「Cache」オブジェクトに格納し、ページをロードする前にそこからアクセスすることです。

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>

これは、JavaScriptでも機能します:)

ユーザーはリンクをクリックし、投稿に移動し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 に答える