How to prevent a browser from going back/forward in history when scrolling horizontally?
Solution 1
So I figured since i've created a web app, why not prompt the user for any unsaved changes which will defer the user from loosing any unsaved changes or ending up on the previous or next page in the browser history.
Here is the solution if any one else comes across this problem like I did:
window.onbeforeunload = function(e) {
return 'Ask user a page leaving question here';
};
Solution 2
history.pushState(null, null, location.href);
window.onpopstate = function(event) {
history.go(1);
};
Demo: http://jsfiddle.net/DerekL/RgDBQ/show/
You won't be able to go back to the previous webpage, unless you spam the back button or hold down the back button and choose the previous entry.
Note: onpopstate
(or event onbeforeunload
) doesn't seem to work on iOS.
Solution 3
If you're on a mac this is caused by the Track Pad Gestures.
System Preferences -> Trackpad -> More Gestures.
Not the JS solution you're looking for, but if you just want to prevent it for yourself you can turn the feature off.
Solution 4
Works in Chrome and Safari (i.e tested with Chrome and Safari):
// el === element on which horizontal scrolling is done
// (can be container of scrolled element or body or any other ancestor)
var preventHistoryBack = function (e) {
var delta = e.deltaX || e.wheelDeltaX;
if (! delta) {
return;
}
window.WebKitMediaKeyError /*detect safari*/ && (delta *= -1);
if (((el.scrollLeft + el.offsetWidth) === el.scrollWidth && delta > 0) || (el.scrollLeft === 0 && delta < 0) ) {
e.preventDefault();
}
};
el.addEventListener('mousewheel', preventHistoryBack);
Solution 5
Here's something that may work for you using CSS' overscroll-behaviour property:
Javascript
document.body.style.overscrollBehaviour = "contain";
CSS
body {
overscroll-behaviour: contain;
}
At the time of writing this, July 10th 2020, this causes scrolling left at the left-end of the page to no longer trigger a backward history-navigation.
I'm not sure what other side-effects this will have on the rest of the user experience. I wish this could be applied inside elements, but it seems like this will only work when applied to the document body.
Comments
-
Steve C almost 4 years
How can one disable a modern browsers default functionality using JQuery or Native JS for going backwards or forwards when scrolling horizontally?
This usually happens when using a trackpad and when scrolled to the end or start of a scrollable div.
-
SimonDever about 11 yearsThe driver and trackpad software is your overlord. See this question answered.
-
-
Steve C about 11 yearsNo offense but manipulating the browser history like that is very nasty in terms of user experience. It's very confusing and annoying. Can see what your getting at though
-
Steve C about 11 yearsYou're exactly right, why would they implement such an annoying way of jumping back and forth in a browser? I think this is so annoying to any user when you are trying to look for something in a horizontal scroll pane.
-
thdoan over 10 yearsYou can still go back if you hold down the Back button.
-
hexalys almost 10 years@steve It's nasty if done for no reason indeed. But there are legit cases for manipulating it that way, at least temporarily... One case I want to apply this to is for skipping the unwanted history trail from the use of the css :target pseudo-class. Or perhaps, disable history, and provide a custom
back button
instead. -
Luke Cousins almost 10 yearsOr when someone is in a payment process and will invalidate their whole payment by using the back button, whereas using the in-page back button will work fine. I can't change the process, it's managed by the payment provider, but I can try to help prevent the user from unknowingly screwing it up!
-
Jacksonkr almost 7 yearsCan also
e.preventDefault(); return false;
-
Jacksonkr almost 7 yearsNote, "wheel" and "mouseweel" operate a bit differently: stackoverflow.com/questions/25204282/…
-
Klimashkin over 6 yearsIt works, but since Chrome 51 you will see '[Violation] Added non-passive event listener to a scroll-blocking 'wheel' event' message in console. But we need nonpassive event, because we call 'preventDefault', and it's unclear how to suppress that message