Подтвердить что ты не робот

Бесконечная прокрутка сверху (обратная) в AngularJS

Я пытаюсь сделать обратный бесконечный свиток. У меня есть список комментариев, в котором я получаю последние 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 в событии прокрутки и вызвав scrollIntoView(), пока я не добавлю таймаут для имитации вызова ajax. С тайм-аутом верхняя строка li прокручивается до появления запроса и отображает новые элементы:/

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

Ответ 1

Вы можете попробовать что-то вроде этого: 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 */ 
});

Ответ 2

Вы когда-нибудь решали это? Мы делаем магию при чтении и настройке scrollTop, но обнаружили, что Safari имеет некоторые странные проблемы с временем, когда дело доходит до настройки и чтения scrollTop, поскольку мы прокручиваем позицию до места, а затем запрашиваем новую позицию, а Safari все еще имеет старую должность.