84

For some web pages we use the swipe left and right functionality of iPhone to pull up the menus. Now with iOS7, they have introduced the ability to go back and forward to previous and next pages of browser history on swipe left and right motions.

But is there a way to disable it for specific pages so as to not have conflicting behavior on the swipe actions?

MeghaK
  • 851
  • 1
  • 6
  • 5
  • It should be distinguished by the swipe starting offscreen. Do you have an example webpage where a conflict occurs? – Rupert Rawnsley Sep 19 '13 at 08:28
  • @RupertRawnsley Add a touchstart/touchmove event to your web page with a console.log('FIRED!'); in it. Move your finger onto the web page from the edge and you will notice the event never fires. Am I right in assuming that this will be the new expected behavior? – Marcus Nov 04 '13 at 00:01
  • @Marcus That sounds like the expected behaviour. I suppose swipe events will only work if they start within some safety margin of the browser window. Technically this is understandable, but the user experience is going to be a bit confusing. The article Vinzzz links to in the answer below correctly points out this is not just a Safari issue. – Rupert Rawnsley Nov 04 '13 at 08:54
  • Has anything changed in regards to the history gesture in iOS8? Has anyone gotten a change to play around with it? – AlexZ Sep 28 '14 at 10:40
  • I've filed an issue on Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=1033464 I know this is an issue that affects more than a single browser, and the question was about Safari, but we have to start somewhere. – naktinis Dec 15 '19 at 14:17
  • You can now (since iOS 13.4): https://stackoverflow.com/a/62308482/1774081 – Rik Jun 10 '20 at 16:29

4 Answers4

15

No, this is done at the OS level, and webpage doesn't get any callback

See this summary of safari changes in iOS7 that might cause problems to your website (including this swipe gesture)

Vinzzz
  • 11,746
  • 5
  • 36
  • 42
13

You can't disable it directly, but the native swipe back only happens if there is something in the browser history.

It won't work in every case, but if you have a single page web app opened in a new tab, you can prevent it from adding to the history by using

window.history.replaceState(null, null, "#" + url)

instead of pushState or

document.location.hash = url
Tom Clarkson
  • 16,074
  • 2
  • 43
  • 51
  • 5
    Yes but this prevents only the history in the app itself when navigating. Other apps may also have pushed a history, therefore iOS will detect those histories too. – dude May 26 '15 at 09:00
7

I had to use 2 approaches:

1) CSS only fix for Chrome/Firefox

html, body {
    overscroll-behavior-x: none;
}

2) JavaScript fix for Safari

if (window.safari) {
    history.pushState(null, null, location.href);
    window.onpopstate = function(event) {
        history.go(1);
    };
}

Over time, Safari will implement overscroll-behavior-x and we'll be able to remove the JS hack

John Doherty
  • 3,669
  • 36
  • 38
  • I added this and on Mac, it does prevent a left swipe from triggering back. However, it breaks the back functionality completely (incl. the Back button), so it can’t be used as a workaround. – Šime Vidas Mar 10 '18 at 21:40
  • In my case that was the goal as I was building a single page app – John Doherty Mar 10 '18 at 21:42
  • 3
    But it’s still possible that someone opens your app by clicking on a link on another website (i.e., if that site links to your app). To fix this, you’d still have to detect swipe gestures via `touchmove` events and only execute the above code if it *wasn’t* immediately preceded by a swipe. It should be possible. – Šime Vidas Mar 11 '18 at 15:11
  • I've updated this to include a CSS only option for Chrome and Firefox – John Doherty Oct 07 '18 at 11:02
  • Are you sure this works on iOS? I've just tested `overscroll-behavior-x: none;` on Chrome on iOS 13 and it had no effect to the swipe-navigation behaviour. Swiping right at the left edge goes back (and even if this is the first page in tab history, it still goes back to the home screen). – naktinis Dec 10 '19 at 15:22
  • 1
    @naktinis on iOS is everything Safari under the hood so it won't work on it. – hromada.dan Feb 24 '20 at 12:18
0

If no history then no swipe.

document.body.addEventListener('click', function(evt) {
  const a = evt.target.closest('a:not([href^="#"])');
    
  if (!a) { return; }

  evt.preventDefault(); 
  history.replaceState({ }, '', a.href);
  location.reload();
});
NSD
  • 428
  • 4
  • 4