0

I want to toggle two divs (screens) and come back to the same scroll location when toggling. The problem is that at the time of scrolling the window still is rendering the old version(wrong timing of scrolling). So lets say if div 'A' max scroll position is 200 and div B max scroll is 100 then the max position I can comeback to 'A' is 100

  <body ng-controller="MainCtrl">
    <div ng-show='showToggle'>
      Screen A
      <ul>
        <li ng-repeat="a in getArray(200) track by $index">
          <a href="" ng-click="show()">
          a:{{$index}}
          </a>
        </li>
      </ul>
    </div>
    <div ng-show='!showToggle'>
      Screen B
      <ul>
        <li ng-repeat="b in getArray(100) track by $index">
          <a href="" ng-click="show()">
          b:{{$index}}
          </a>
        </li>
      </ul>
    </div>
  </body>

JS:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, $window) {
  $scope.showToggle = true;
  $scope.getArray=function(size){
    return new Array(size);
  }

  $scope.scrollState = {};

  $scope.show = function(){
    //Saves current window position of scroll for the future
    $scope.scrollState[$scope.showToggle] = $window.pageYOffset;
    //Activates different div with different scroll length
    $scope.showToggle = !$scope.showToggle;


    //At this time window scroll length is still showing for previous div
    $window.scrollTo(0, $scope.scrollState[$scope.showToggle]);
  }
});

What would be the recommended solution for this? Basically I just want to know when is the earliest point when window's 'size' is accurate (appropriate div rendered/hidden) and how can I listen for this event in angular.

plunker

1 Answer 1

1

Use $timeout to let angular finish its dirty checking work and updates the DOM and then scroll the window.

    var app = angular.module('plunker', []);

    app.controller('MainCtrl', function($scope, $window, $timeout) {
      $scope.showToggle = true;
      $scope.getArray=function(size){
        return new Array(size);
      }

      $scope.scrollState = {};

      $scope.show = function(){
        //Saves current window position of scroll for the future
        $scope.scrollState[$scope.showToggle] = $window.pageYOffset;
        //Activates different div with different scroll length
        $scope.showToggle = !$scope.showToggle;

    $timeout(function(){
        //At this time window scroll length is still showing for previous div
        $window.scrollTo(0, $scope.scrollState[$scope.showToggle]);
});
      }
    });
Sign up to request clarification or add additional context in comments.

1 Comment

It will work in all the cases. $timeout waits for angular to finish dirty checking and DOM updation. $timeout is being used widely even within angular code and angular-ui code, certainly its stable enough.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.