14

逆無限スクロールをしようとしています。最新の 10 件のコメントを受け取るコメント リストがあり、ユーザーが上にスクロールて次の 10 件を取得できるようにしたい - 「前の取得」リンクで最新のコメントを表示する FB と同様ですが、リンクではなくスクロールイベント。

私はhttp://jsfiddle.net/vojtajina/U7Bz9/から始めて、それを逆の無限スクロールに変更しようとしましたが、すぐに次のような結果になりました:

  function Main($scope, $timeout) {
    $scope.items = [];

    var counter = 0;
    $scope.loadMore = function() {
      // simulate an ajax request
      $timeout( function() {
        for (var i = 0; i < 5; i++) {
          $scope.items.unshift({id: counter});
          counter += 10;
        }}, 1000);
    };

    $scope.loadMore();
  }

  angular.module('scroll', []).directive('whenScrolled', ['$timeout', function($timeout) {
    return function(scope, elm, attr) {
      var raw = elm[0];

      $timeout(function() {
        raw.scrollTop = raw.scrollHeight;
      }, 1100);

      elm.bind('scroll', function() {
        // note: if test for < 100 get into infinite loop due to 
        // the delayed render
        if (raw.scrollTop === 0) {
          var sh = raw.scrollHeight
          scope.$apply(attr.whenScrolled);
          // the items are not loaded and rendered yet, so
          // this math doesn't work
          raw.scrollTop = raw.scrollHeight - sh;
        }
      });
    };
  }]);
  ​

http://jsfiddle.net/digger69/FwWqb/2/

問題は、次の 10 個のアイテムが取得されると、それらがリストの一番上に追加され、リスト全体が再レンダリングされ、リストの最初にあったアイテムが完全にスクロールされて表示されなくなることです。フィドル項目では「40」が一番上にあり、スクロールして(少し下に)スクロールしてから上にスクロールすると、項目「90」が一番上になります。レンダリング後にスクロール領域の上部に「40」を保持するための適切な戦略を探しています。

注:フィドルでは、スクロールイベントの一番上のliを​​保存し、タイムアウトを追加してajax呼び出しをシミュレートするまでscrollIntoView()を呼び出すことで、機能させることができました。タイムアウトを使用すると、リクエストが戻ってきて新しい要素がレンダリングされる前に、上部の li がスクロールして表示されます:/

var top = elm.find("li")[0];
scope.$apply(attr.whenScrolled);
top.scrollIntoView();
4

2 に答える 2

22

次のようなものを試すことができます: http://jsfiddle.net/mNFmf/4/

これにより、div の一番下までスクロールされます。

$timeout(function() {
    raw.scrollTop = raw.scrollHeight;          
});    

これにより、div がリストの最初の項目までスクロールしなくなります。

var sh = raw.scrollHeight
scope.$apply(attr.whenScrolled);
raw.scrollTop = raw.scrollHeight - sh;

アップデート

ajax リクエストの問題を克服するには、promisesを使用してみてください。

http://jsfiddle.net/mNFmf/8/

ローダーは次のようになります。

$scope.loadMore = function() {
  var deferred = $q.defer();

  // do ajax request here and after getting the result call:   
  deferred.resolve();

  return deferred.promise;
};

そして反対側では:

loadMore.then(function() { 
  /* do whatever you want after the ajax request has been fulfilled */ 
});
于 2012-12-07T11:36:00.143 に答える
0

これを解決したことがありますか?読み取りと設定scrollTopでいくつかの魔法を行っていますが、スクロールトップの設定と読み取りに関しては、ある位置までスクロールしてから新しい位置を照会し、Safari にはまだ古い位置があるという奇妙なタイミングの問題があることがわかりました。

于 2013-02-25T10:20:11.340 に答える