Reputation: 8582
I want to disable the two finger swipe that causes Chrome going back or forward. I have a website where the user might lose progress on his work if he doesn't specifically saves.
I have tried using window.onbeforeunload
but that doesn't seem to work if I have hashes in the url (back forward would change between www.example.com/work/#step1#unsaved www.example.com/work/#step0) and the event doesn't seem to trigger.
I was about to switch to another solution but today I noticed that in Google Docs it's completely disabled. How did they achieve that?
Upvotes: 53
Views: 37860
Reputation: 115
Posting a non-CSS answer, which sometimes you don't have access to.
Run chromium
/ chrome
with the disable-features=OverscrollHistoryNavigation
:
# Run Chromium or Chrome with following flag
chromium --disable-features=OverscrollHistoryNavigation
Other gesture-related flags are usually recommended (such as the one that disables zooming via pinch, --disable-pinch
), can be found here: https://niek.github.io/chrome-features/, which is a blog post recommended on the official docs (here, down bottom)
Upvotes: 0
Reputation: 2335
The top answer from: Disable Chrome two fingers back/forward swipe worked for me. In your CSS file:
html, body {
overscroll-behavior-x: none;
}
Upvotes: 123
Reputation: 836
Assuming you have a horizontal-scrolling element, adding overscroll-behavior-x: contain;
is the easiest way prevent the scroll action from spilling out into the page and causing the navigation.
https://caniuse.com/#feat=css-overscroll-behavior
Upvotes: 10
Reputation: 157
You can disable back/forward with this code:
document.addEventListener("wheel", function(event) {
event.preventDefault();
}, { passive: false });
Note that adding { passive: false } is essential, at least in Chrome. If you only want to disable back/forward in certain areas you can use code like this (assuming you're using jquery and you add the class disable-back-forward to the sections where you want to disable back/forward):
document.addEventListener("wheel", function(event) {
if ($(event.target).closest('.disable-back-forward').length)
event.preventDefault();
}, { passive: false });
Upvotes: 1
Reputation: 658
I've been working on something similar where I want to override the forward/backward history swiping gesture. Depending on what your swipe area is you can tweak the selector as follows:
html { touch-action:none; }
This is the associated documentation that gives you all the properties to all touch actions like panning or zooming features built into the browser.
https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action
Upvotes: 2
Reputation: 1169
Disable or replace swipe gestures for Google Chrome 61
The question that leads me here was marked "duplicate" and closed to answers. I believe this answer is better suited for the "duplicated" question, however, I feel this answer could possibly save time for someone landing on either question.
Better question: Disable navigation swipe on Chrome browser in javascript
This Google developers article helped me to allow the e.preventDefault() to work and prevent swipe gestures as of Chrome 61.
https://developers.google.com/web/updates/2017/01/scrolling-intervention
givanse's answer to the following was the code that I used to write my own swipe event handlers:
Detect a finger swipe through JavaScript on the iPhone and Android
In summary, the following two events are used to implement the swipe gestures:
handleTouchStart (e) {
...
},
handleTouchMove (e) {
...
e.preventDefault()
}
As of Chrome 56, the default behavior is to make the event listeners passive and thus disable the ability to prevent Chrome's swipe gestures. To override this behavior, event listeners can be added as follows:
document.addEventListener(
'touchstart',
this.handleTouchStart,
{passive: false}
)
document.addEventListener(
'touchmove',
this.handleTouchMove,
{passive: false}
)
By passing the {passive: false} object as the third parameter to the addEventListener method, the listener is registered as active and can stop Chrome's default behavior with the e.preventDefault() event method.
Upvotes: 8
Reputation: 59
I was able to disable it by typing chrome://flags in the address bar and heading down to "Overscroll history navigation" and setting it to "Disabled" from the dropdown.
Upvotes: 0
Reputation: 1786
Building on both the previous answers given by @roy riojas and @redgetan - I combined their answers to allow for this to be dynamic and prevent both forward and backwards - again - per @roy's comments - you must know the class of your element, and for this implementation - the class of the nested element that is actually being scrolled
(function ($) {
$(document).on('mousewheel', function(e) {
var $target = $(e.target).closest('.scrollable-h');
var scroll = $target.scrollLeft();
var maxScroll = $target.find('.scrollable-h-content').width() - $target.width();
if(scroll <= 0) {
if(scroll <= 0 && e.originalEvent.wheelDeltaX >= 0) {
e.preventDefault();
}
}
if(scroll >= maxScroll) {
if (scroll >1 && e.originalEvent.wheelDeltaX <= 0) {
e.preventDefault();
}
}
});}(jQuery));
Upvotes: 2
Reputation: 953
Make the specific page open in a new tab/window by default (by putting target="_blank"> in hyperlink). That way there'll be no previous page to go back to.
Or prevent Horizontal Scrolling by default. To do that, you can use jquery.mousewheel to do:
$(document).on("mousewheel",function(event,delta){
// prevent horizontal scrolling
if (event.originalEvent.wheelDeltaX !== 0) {
event.preventDefault();
}
});
Upvotes: 10
Reputation: 41958
You're looking at the problem at the wrong level. OnBeforeUnload is simply not triggered because there is nothing being unloaded from the browsers perspective. Therefore you have, quite bluntly, implemented the wrong mechanism for versioning - fragments are for page states, not document states as you are using it now.
If you insist on maintaining state through hash fragments you need to use another mechanism to guard against page state changing. Since all current browsers support LocalStorage I'd use that. And well, while at it, put all the document state data there instead of in the URL, since that is how Google Docs does it and that is why they don't have this issue.
Upvotes: -4
Reputation: 2476
Hi this worked for me on chrome but not for the entire page, but for places where I have scrollable content.
In Google Docs (Spreadsheets) it seems to be working because they don't have a back page to go. If you navigate to another URL (manually) it will not prevent you from navigating back.
$(document).on('mousewheel', function(e) {
var $target = $(e.target).closest('.scrollable-h');
if ($target.scrollLeft () <= 4) {
$target.scrollLeft(5);
return false;
}
});
One thing to keep in mind is that the code above is making two assumptions:
Important: - This only prevents the back swipe gesture, when is done fast, if you do it very slow it will still trigger sometimes.
You can take a look to a proof of concept here. http://jsfiddle.net/royriojas/JVA6m/#base
Upvotes: 0