IOS8 Safari website links do not work after scroll

2019-05-28 17:55发布

问题:

I have an Angular website with a Bootstrap theme built primarily for iPhone users and since the IOS8 update I have found problems relating to scrolling. The site behaves fine until I scroll, once I have scrolled the links behave erratically eg if I press Button 2, the link from Button 1 will open. Also some CSS3 styles are not working eg :nth-child(even) I have searched for days trying to find a link between this behaviour and a scrolling bug but I can't find a fix anywhere. Unfortunately I cannot post the website link but it consists of a fixed Header and Footer, and a div set to overflow: auto; Any help is greatly appreciated :)

NB: I am using multiple accordions with in the scrollable element

Style for scrollable element

    .scrollable {
      overflow: auto;
      -webkit-overflow-scrolling: touch;
      position: absolute;
      top: 47px;
      bottom: 0px;
      left: 0px;
      right: 0px;
    }

Update: I have added an image from IOS simulator to illustrate the problem. I used Inspect Element to highlight the placement of the Anchor tag after scrolling. It's like Safari does not reset the position after scrolling.

Update: I think that this problem is related to the footer which is positioned using position: fixed; I haven't been able to confirm this yet but it looks like the root of the problem.

回答1:

We have a similar issue. The result of the analysis based on reproducible observations: The vertical Position of the touch is not passed correctly to Safari, i.e. if you touch the screen at x/y position 100/200, the Position 100/300 is passed to the browser. This Delta becomes bigger and bigger the more often you touch the Screen. You can observe this best if you have a series of elements in different rows. At the beginning you click on row 1 and row 1 is activated. A bit later you click on row 2 and row 1 is activated, and then row 3, row 4 till you touch the most bottom row, and then the y coordinate passed is even above the 0 position. Before looking at the user workaround for our site, please note that we have the following event handler for rotation change:

function doOnOrientationChange()
{
  switch(window.orientation) 
  {
    case -90:
    case 90:
		viewport = document.querySelector("meta[name=viewport]");
		viewport.setAttribute('content', 'initial-scale=0.9,width=device-width');
      break; 
    default:
		viewport = document.querySelector("meta[name=viewport]");
		viewport.setAttribute('content', 'initial-scale=0.75,width=device-width');
      break; 
  }
}

The Workaround for the user:

  • Zoom in and out again. This solves the issue until the page is changed or tab is closed
  • Alternatively: change the rotation to Portrait and back

If I add user-scalable=no to the view-port setting, the issue does not appear at all:

function doOnOrientationChange()
{
  switch(window.orientation) 
  {
    case -90:
    case 90:
		viewport = document.querySelector("meta[name=viewport]");
		viewport.setAttribute('content', 'initial-scale=0.9,width=device-width,user-scalable=no');
      break; 
    default:
		viewport = document.querySelector("meta[name=viewport]");
		viewport.setAttribute('content', 'initial-scale=0.75,width=device-width,user-scalable=no');
      break; 
  }
}

But this is not a solution for us. Actually we had added this setting after iOS7 was released. It was just a Workaround for a iOS7 bug. Later we found another workaround and we could remove this restriction. Now after releasing iOS8, I have a Kind of dejavú, since we could add the same setting, this time as a workaround for a bug in iOS8. But fortunately there is another workaround which works fine for us. Directly after the page is loaded, the following is launched which simulates a zoom out and in by the user:

function ios8BugFixPart1() {
  // zoom out
  switch(window.orientation) 
  {
    case -90:
    case 90:
		viewport = document.querySelector("meta[name=viewport]");
		viewport.setAttribute('content', 'initial-scale=0.8,width=device-width');
      break; 
    default:
		viewport = document.querySelector("meta[name=viewport]");
		viewport.setAttribute('content', 'initial-scale=0.70,width=device-width');
      break; 
  }
	setTimeout(ios8BugFixPart2, 200);
}
function ios8BugFixPart2() {
  // zoom in
  switch(window.orientation) 
  {
    case -90:
    case 90:
		viewport = document.querySelector("meta[name=viewport]");
		viewport.setAttribute('content', 'initial-scale=0.9,width=device-width');
      break; 
    default:
		viewport = document.querySelector("meta[name=viewport]");
		viewport.setAttribute('content', 'initial-scale=0.75,width=device-width');
      break; 
  }
}
setTimeout(ios8BugFixPart1, 1000);

I hope this will help some of you as well.

PS: is there any possiblity to prevent the Cupertino guys from introducing new OS Versions, even if the changes are so small as it is the case this time?



回答2:

This is what ultimately worked for me, strange as it is:

$(window).load(function() {
    var deviceAgent = navigator.userAgent.toLowerCase();
    var agentID = deviceAgent.match(/(iphone|ipod|ipad)/);
    if (agentID) {

    setTimeout(function(){
        window.scrollTo(1, 1);
    }, 100);

    // http://davidwalsh.name/hide-address-bar
}

}); 


回答3:

A developer at work managed to solve this issue by removing transitions between pages. See the code he commented out below. It was found in controllers.js. Hopefully this example will help you find the transition code in your project.

$scope.slide = '';
$rootScope.back = function() {

//$scope.slide = 'slide-right';
 $window.history.back();
}
$rootScope.go = function(path){
//$scope.navLeft = false;
//$scope.navRight = false;
//$scope.slide = 'slide-left';
$location.url(path);
}