Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome browser on iOS with ngRepeat overscrolls on reload

I've hit an incredibly annoying edge case with a small one-page AngularJS app I've been developing for a client.

For simplicity, consider the following HTML code:

<div ng-controller="ServiceGuideCtrl">
    <h1>Care Assessment</h1>
    <form ng-submit="loadResults($event);">
        <div>
            <h2>Is this for you or a loved one?</h2>
            <ul>
                <li><input type="radio" ng-model="who" value="Do you"> Me</li>
                <li><input type="radio" ng-model="who" value="Does your loved one"> Loved one</li>
            </ul>
        </div>
        <div ng-repeat="question in questions">
            <h2>{{ question.text }}</h2>
            <ul>
                <li><input type="radio"> Yes</li>
                <li><input type="radio"> No</li>
            </ul>
        </div>
        <p ng-show="who"><input type="submit" value="Submit answers"></p>
    </form>
</div>

The Angular controller:

app.controller('ServiceGuideCtrl', ['$scope', '$timeout', '$window', function($scope, $timeout, $window) {

        $timeout(function() {
            $window.scrollTo(0,0);
        });

        $scope.$watch('who', function(value) {
            $scope.questions = [];
            if (typeof $scope.who !== 'undefined') {
                for (var i=0; i < 20; i++) {
                  $scope.questions.push({
                      'text': $scope.who + ' need this particular thing?'
                  });
              }
            }
        });
}]);

The problem is in any iOS platform on the Chrome browser:

  1. Select one of the "Me/Loved one" options
  2. Scroll down through the questions (preferably the bottom), but don't click "Submit answers"
  3. Reload the page while still being scrolled down
  4. Page will "jump" to the saved scroll position, but since the ng-repeat elements aren't loaded, it overscrolls to a completely dark grey area.
  5. Changing orientation or just slightly scrolling the page back up jumps the page to where it's supposed to be.

Here's a screenshot of what it looks like:

Blank screen completely grey due to iOS overscroll

Plunker: Click here

If you want to test this on Chrome using your own iOS device (since Plunker uses iFrames and makes weird things happen with scrolling on mobile devices).

As you can see, $window.scrollTo(0,0) is doing nothing for me. It seems that Chrome for iOS applies its saved scroll position after the DOM and Angular is loaded. If I use a timeout of around 20-30 ms, the page flickers off-screen then back to the top, confirming my theory. Problem is that the 20-30 ms value is still unreliable (it works half of the time), and any bigger values would cause a much more obvious screen flicker.

How can I make it so that when a page with ng-repeat elements is reloaded on iOS for Chrome, it doesn't overscroll to the blank grey area? Is this potentially a bug from the iOS Chrome browser?

It should be noted that I would accept this as a browser bug (read: not my problem), but members of my office are on an anti-AngularJS vendetta so I'd like to fix it.

like image 366
sjagr Avatar asked Apr 09 '15 18:04

sjagr


1 Answers

I don't own an iPhone and hardly understand the problem, but since it seems that the smarphones applies an undesired scroll event on the whole page, I would work around that by setting a fixed height to the document, and instead handling the overflow scroll within your container.

html { height: 100%; }
body { height: 100%; }
.container { height: 100%; overflow: scroll; }

http://plnkr.co/edit/gDQNIY6kFuLnskn85yXj?p=preview

like image 193
floribon Avatar answered Sep 22 '22 02:09

floribon