Not being able to completely disable the two-finger swipe gesture to navigate through the browser history for a whole website is a constant annoyance to me. Up until this point, it was at least possible to prevent that behavior by calling preventDefault() on the mousewheel event.
This does not seem to be working anymore in Chrome 59.
Here is how to reproduce it:
Start the gesture somewhere on the page, then cancel it
From there on, preventDefault has no effect.
Does anyone have a solution to this?
Examples
Zenkit and Airtable both call preventDefault when you scroll inside their table view. It seems to be working at first, but as soon as the gesture was recognized and then canceled at least once (outside the table, where prevent default is not called), preventing the gesture doesn't work anymore (even inside the table). So from there on, scrolling to the left inside the table is almost impossible because it always triggers the gesture.
In Trello`s kanban view it only occurs if you're at the left or right edge of the scroller. But I guess that is because they use native scrolling while Zenkit and Airtable use css translation instead.
I tried creating an invisible scroll container on top of the content once the user starts scrolling and removing it afterwards. This reduces the problem significantly but doesn't work in all of the cases.
Example Code:
https://codepen.io/anon/pen/gRKaMX
There are 3 boxes in this pen.
The fist one scrolls natively using overflow: scroll. Here the gesture can only be triggered if scrollLeft is 0.
The second one has an event listener attached that calls preventDefault on every mousewheel event. This prevents the gesture at first but once you started it anywhere else on the page, it doesn't work anymore.
And lastly there is a third div that you can always start the gesture on.
StackOverflow wants me to inline the code as well, so here it is:
HTML:
Native Scrolling:
<div id="native-scrolling" class="box">
<div></div>
</div>
Prevent gesture by calling prevent default. Only works if you didn't start the gesture anywhere else, yet:
<div id="prevent-gesture" class="box"></div>
Just a normal div:
<div class="box"></div>
JavaScript:
$('#prevent-gesture').on('mousewheel', function (event) {
event.preventDefault();
});
CSS:
.box {
height: 100px;
width: 200px;
background: black;
}
#native-scrolling {
overflow: scroll;
}
#native-scrolling > div {
width: 200%;
height: 10px;
}
Thanks in advance,
Jesse
Edit: About the accepted answer
Restarting Chrome fixes this issue temporarily but it keeps coming back. I'm on Chrom 69 now and it still occurs.
Have you tried turning it off and on again?
See my answer on https://bugs.chromium.org/p/chromium/issues/detail?id=889846#c3
This is expected behavior on Chrome.
If you are developer, please try to use overscroll-behavior to fix it.
https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior
If you are user, please try to disable overscroll swipe on MacOS
settings. See thread you provide.
https://community.airtable.com/t/triggering-back-gesture-in-chrome-on-macos-when-scrolling-to-the-left/3074/6
For event.preventDefault() is not cancellable every wheel event.
https://github.com/w3c/uievents/pull/171/commits/824a919756b4c5702a9878efd45ea5c93a2d73a3
Related
SAFARI ONLY
I have encountered weird bug on desktop Safari.
I wanted to display modal after reaching some point when scrolling website. Unfortunately when we do that on safari modal is not clickable (z-index issue?). I've been using react + react-modal, but I think that this issue is not related to any of those.
Source code + demo: https://codesandbox.io/s/p5x9331y8x
I've noticed that when we wrap triggering function in setTimeout() we will be able to see that modal stops working only when it appear while scroll event. https://codesandbox.io/s/3q7rmpj1mq
Ofc setTimeout() is not a solution here...
I've found issues related to this but any of them is not matching my problem exactly:
https://github.com/reactjs/react-modal/issues/369
https://css-tricks.com/forums/topic/safari-for-ios-z-index-ordering-bug-while-scrolling-a-page-with-a-fixed-element/
Also when there is no overflow: hidden on body it works properly but thats not a solution here either (obviously we want to prevent background from scrolling).
Note: Regarding demo, modal appears after reaching last section of page (this problem is recreated). It's good to open page in full screen for testing.
Any help would be really appreciated.
Issue was solved by changing from overflow: hidden to overflow-y: hidden...
I'm developing a web application based on EmberJS, that should be running on multiple device types. The application includes dialogs, that are handled using the ember-modal-dialog and liquid-wormhole addons.
When opening the dialog on an iPhone, scrolling within the dialog eventually stops working, and instead of scrolling the content, some underlaying(?) elements are overlapping the dialogs content from the top or bottom (depending on the scroll direction). It's actually hard to explain, so I've made a video:
https://drive.google.com/file/d/12Xfvxvx89r91svEyybMf1j6HFD3v_Tkl/view
Also, you can try it yourself. Click on the following link, and then on the button of the first item on the page.
https://rkr9z8g.suitepad.io/category/6463/page/22280
Does anyone knows or have an idea, how to fix the problem?
I've got same problem in my project. But i found that some duplicate style on my div. Try remove overflow-y: scroll and add -webkit-overflow-scrolling: touch. Hope that helps.
Is there way to interrupt iOS scrolling using javascript?
Example 1: user is scrolling content by moving his finger through device screen. When some event happens user continue moving his finger without raising but there is no scrolling anymore.
Example 2: user initiated scrolling but stopped his finger without raising. Some event happens and scrollbar disappears.
Example 3: Momentum scrolling completely stops when some event happens.
The first case could probably be covered using the following piece of code from another question
<script type="text/javascript">
function blockMove() {
event.preventDefault() ;
}
</script>
<body ontouchmove="blockMove()">
However, it will only work on iOS 8+. As for the other two cases I'm not aware of any method to do that.
If you're talking about interrupting the iOS inertia/momentum scrolling, then I might have something for you.
First of all, you need to add fastclick.js. The lib removes the 300ms click delay on mobile devices and enables event capturing during inertia/momentum scrolling.
After including fastclick and attaching it to the body element, my code to interrupt scrolling looks like this:
scrollElement.style.overflow = 'hidden';
setTimeout(function() {
scrollElement.style.overflow = '';
}, 10);
The trick is to set overflow: hidden, which stops the inertia/momentum scrolling. Please see my fiddle for a full implementation of stop scrolling during inertia/momentum.
I have a form within an iframe on a website that I am testing on iPad. It seems that the touch events do not work on the inputs with type "text" or textarea elements. Swiping or touching does nothing on those areas and the keyboard does not pop up. The combo box (select) elements I can interact with just fine. Is anyone else having this problem?
I have no issues on iPad iOS 4.3 only on iPad iOS 5. The markup and styling are pretty standard, but if no one else is experiencing this issue I can post the code. The only unique element that I can think of is that all of the markup is loaded dynamically using jQuery tmpl.
I have only seen documentation online regarding scrolling of textareas but this seems to be a separate issue.
Correction *
I just hit the page directly (outside of the iframe) and am still having the same problem. So has anyone seen this behavior before? Is it due to strange CSS styling? Z-indexing?
OKAY GOT IT! So I noticed that click events were registering but default drag behavior was not. I also remembered that I had implemented a jquery ui extension for draggable behavior that hooked touch events into their click and mousemove event handling. That was the culprit. I removed that extension and added this instead : github.com/furf/jquery-ui-touch-punch This works on both iOS 4.3 and iOS 5.1
I guess that has to be a bug in iOS...
Or could you post a link to what you have made?
I could test it on my iPod Touch...
I've had this problem for days now, and from googling around, most of the internet has too. But none of the posts contained an answer. This is the solution that worked for me. It's based on https://gist.github.com/tamarasaurus/dcf2d0331043586421f3. Hopefully this will help people in the future, or at least point them in the right direction.
document.addEventListener('keydown', function(e) {
window.focus();
});
document.addEventListener('touchend', function(e) {
window.focus();
});
I'm programming a Webpage/-Application for the iPhone. I need to scroll to a specific position after page reload, no matter where I scrolled to while using the page before.
The script I use works fine in firefox but not in mobileSafari. In contrast to firefox, mobileSafari seems to save the position I scrolled to previously and jumps there after reload, ignoring my scrollTo triggered on reload.
This is the code I use:
function scroller(){scrollTo(1000,1000);}
window.addEventListener("load",scroller, false);
It works with click-events that I trigger manually. If I click a button to trigger the scroll function than the scrolling is done.
I tried to trigger the click via a synthetic event javascript, but this does not work either.
Is there any way the scrolling can be archived on reload and/or other not explicitly user triggered events?
I did not find a solution for the actual problem which seems to be a bug. But I found a workaround. This is not to trigger the scrolling directly via an onload event but to use a setTimeout()
init(){
setTimeout(scrollTo(0, 1000), 10)
//more code
}
//more code
window.onload=init;
What about the iscroll prototype !?