Prevent page navigation on horizontal scroll
Asked Answered
C

2

14

I am using a mac trackpad.How to prevent the page going back and next to visited pages on horizontal scroll ?.

I tried to prevent the wheel events but it doesn't works most of the time.

container.addEventListener('wheel', function(ev) {
    ev.preventDefault();
    ev.stopPropagation();
    return false;
}, {passive: false, capture: true});

even I tried blocking with mousewheel event which also leads to page navigation.

Caressive answered 31/5, 2018 at 3:31 Comment(5)
mvce ?Naphthalene
What do you mean "horizontal scroll"? Mouse wheels scroll vertically. Do you mean tipping the wheel to one side or another (supported on some mice)? If so, ensure those actions aren't mapped to back/forward in the mouse configuration (perhaps in an app from the manufacturer, or OS configuration).Heroworship
I am using mac trackpad to scroll. @Heroworship "horizontal scroll" - i meant scrolling in x direction (left and right)Caressive
Then it's the same as for a wheel that tips--check your trackpad software or OS configuration for trackpad gesture support.Heroworship
If you're building a public facing website for users, you might want to consider whether overriding their default browser behaviour actually serves them, when they can change it theirselves if they want to.Providence
G
17

It has nothing to do with a webpage nor its events; this is specific system behavior and I don't think it can be blocked from javascript level.

If you want to disable it - go to: Apple Logo > Preferences > Trackpad > More gestures and uncheck Swipe between pages

// EDIT

Ok, I googled a bit and it seems I was wrong- there is a solution to that and basically is pretty simple:

document.body.addEventListener('mousewheel', function(e) {
  e.stopPropagation();
  var max = this.scrollWidth - this.offsetWidth; // this might change if you have dynamic content, perhaps some mutation observer will be useful here

  if (this.scrollLeft + e.deltaX < 0 || this.scrollLeft + e.deltaX > max) {
    e.preventDefault();
    this.scrollLeft = Math.max(0, Math.min(max, this.scrollLeft + e.deltaX));
  }
}, false);

Just tested this on OSX Chrome 67

Gladygladys answered 23/6, 2018 at 7:16 Comment(10)
It didn't work and I just wanted to block scroll/wheel over only on one container.Caressive
So instead of document.body pass your element, like document.getElementById. Where are you testing this, browser version?Gladygladys
Yes i did it over the container. but it didn't worked out :(. Browser: Chrome 67Caressive
That's strange, as it work's for me and i work on osx with Chrome 67, though- try adding additional e.stopPropagation() as in edit above, maybe it's bubbling issueGladygladys
Nope, not working. I tried all possible ways even i blocked in the capturing phase. It didn't worked out. I dunno what i am doing wrong here.Caressive
@PrasannaRkv please attach a fiddle then. Are you using touchbar or magicmouse?Gladygladys
Here's the fiddle codepen.io/PrasannaRkv/pen/pKqJaz I am using macbook's touchpad. Even i get the same results with magic mouse or trackpad.Caressive
@PrasannaRkv That pen works for me on Chrome & macbook. Note that, naturally, the cursor has to be on the grey container for the eventlistener to block the back/forward gesture — outside of the container scrolling and gestures work normally. Also: do you have any 3rd party software that would mingle with the gesture (e.g. BetterTouchTool)?Joby
not once if i have triggered the page navigation via the gesture. I couldn't block the scroll from that point. if i have visited the page via mouse gesture i.e if swipe back and came bak to the page again. it never worked. And do you have a history of pages so that back and forward will be enabled ? If not the issue won't be there at all.Caressive
As of 2022, this can be managed a lot easier with overscroll-behavior in CSS. See this answer.Hankow
H
16

As of 2022 this can be managed in all browsers with the overscroll-behaviour CSS property: https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior

For example:

body {
  overscroll-behavior-x: contain;
}

Or, you could apply it just on a single element that has overflow scroll, allowing swipe navigation in the rest of the page, just blocking it in the portion they would be scrolling:

.someScrollingComponent {
  overflow: scroll;
  overscroll-behavior: contain;
}

The MDN docs describe property contain:

Default scroll overflow behavior (e.g., "bounce" effects) is observed inside the element where this value is set. However, no scroll chaining occurs on neighboring scrolling areas; the underlying elements will not scroll. The contain value disables native browser navigation, including the vertical pull-to-refresh gesture and horizontal swipe navigation.

(Emphasis added)

Healey answered 21/10, 2019 at 20:40 Comment(2)
Setting it on html did not work for me, however setting it on body did the trick.Quarterhour
Boom! Adding this prevents the swipe back navigation for Apple's Magic Mouse.Aron

© 2022 - 2024 — McMap. All rights reserved.