-
Notifications
You must be signed in to change notification settings - Fork 400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
iNoBounce breaks horizontal scrolling #50
Comments
Duplicate of #2? |
I ran into the same limitation and ended up writing my own micro tool for this with direction detection and a few perfomance optimizations. It allows for both horizontal and vertical scrolling: |
@monokee a pull request would have been nicer, it's pretty clear you based your work on iNoBounce. |
tbh I've never done a pull request before and don't really know how that works. feel free to adopt anything you might find useful (that's why I'm sharing it here) |
I refactored and improved the approach a little by moving most of the pre-selection logic into the touchstart listener to greatly simplify the touchmove handler and further optimize performance . All that is needed for reliable results should be these two document-level event handlers (set {passive: false} in supported environments!) // Defined outside of continuous input handlers to tame GC
let finger, el, style, overflowY, overflowX, initX, initY, atTop, atBtm, targetScrollAxis;
// document.addEventListener('touchstart', touchStart);
const touchStart = e => {
el = e.target;
initX = e.changedTouches[0].pageX;
initY = e.changedTouches[0].pageY;
atTop = false;
atBtm = false;
// Find scrollable element
while (el !== document.body) {
style = getComputedStyle(el)
if (!style) break;
overflowY = style.getPropertyValue('overflow-y');
overflowX = style.getPropertyValue('overflox-x');
// Detect scrollable elements scroll axis
if (el.scrollHeight > el.offsetHeight && (overflowY === 'auto' || overflowY === 'scroll')) {
targetScrollAxis = 'y';
// Top or bottom end
if (el.scrollTop < 1) {
atTop = true;
} else if (el.scrollTop + el.offsetHeight === el.scrollHeight) {
atBtm = true;
}
} else if (el.scrollWidth > el.offsetWidth && overflowX !== 'hidden') {
targetScrollAxis = 'x';
} else {
targetScrollAxis = '';
}
if (targetScrollAxis) {
return;
} else {
el = el.parentNode;
}
}
};
// document.addEventListener('touchmove', touchMove, {passive: false});
const touchMove = e => {
finger = e.changedTouches[0];
switch (targetScrollAxis) {
case 'y':
if ((atTop && initY < finger.pageY) || (atBtm && initY > finger.pageY))
e.preventDefault();
return;
case 'x':
if (Math.abs(finger.pageY - initY) > 5)
e.preventDefault();
return;
default:
e.preventDefault();
return;
}
}; Tested on iOS 11.3 Safari & Chrome This is so trivial that I feel like I'm missing something. Would be interested in more tests and suggestions for futher improvement! |
@monokee does it scroll horizontally when you're scrolled to the top or bottom of the element? |
@lazd I've tested this on elements that are either horizontally or vertically scrollable, not both at the same time. I should test for that and report back. |
In case an element is scrollable on both X and Y axes here's what will happen: If we're at the top or bottom end of a Y axis scrollable, that information, along with the initial touch coordinates is passed from the touchstart to the touchmove: targetScrollAxis = 'y';
atTop || atBottom = true; If we're at the top or bottom of a Y axis scrollable element the touchmove handler additionally checks if we're attempting to swipe away from the top and prevents the move only if we are in fact pulling down, thus preventing the default behavior. If we were to strictly pan along the x axis the check for initY < finger.pageY would fail because a strict x-pan move would not alter the current y coordinate and thus the default behavior (panning horizontally) would not be prevented. This is expected and exactly what we want and the same is true for the bottom end. In real world usage it can happen that an intended x-pan on an element that is scrollable on both axes also slightly moves on the y axis. If this unintended y-move is in the direction away from the elements current top or bottom boundary the x-move will inevitably be prevented and there is nothing that can be done to circumvent this. Definitely something to keep in mind as a potential edge case but probably quite rare in real world situations. Everything else should be working exactly as expected according to my tests. Edit: Actually I'm checking for either X or Y scrollables in the above implementation, the handler would need a slight modification to allow for XY scrollable elements (if + if instead of if + else if essentially). I'll patch that up in the morning. |
Looks like I was overthinking the problem. The code I posted above already selects y over x when an elment is scrollable on both axes so the edge case stands but the code doesn't need modification. I did look at the iNoBounce source and don't quite get why it's looking for the 'overscroll: touch' property or if there are any scenarios where it is indeed better to continuously search for scrollables during touchmove so there might be something I'm missing. Thoughts? @lazd |
My project also has this problem. |
I can only turn it off where I need to roll horizontally |
Hi guys, any solution for this? iNoBounce works great for my project as it fixes all the scrolling issues it had, however, it breaks the horizontal scrolling of one element. How can it be fixed? @monokee I tried your script, but couldn't make it work. do I just need to add the JS file to my footer? or what else? could you add some instructions? I'm just using plain html, jquery and js files. thank you so much! |
It should have been fixed. |
Horizontal scrolling is still bugged on my end if iNoBounce 0.2.0 is used. It requires multiple "touches" to initiate the scrolling and most of the time it will be just "stuck". Any updates on this horizontal scroll behavior? |
@himynameisubik this PR was supposed to fix it, but apparently it causes bounce #65 (comment) |
Hmm, if it fixes the stuck horizontal scrolling but re-introduces the bouncing there is no point to it? Or am I missing something? |
@himynameisubik yeah that's what was reported, hence not merging... If you want to test other PRs and see if they get us closer, I'm down to investigate further. |
I tried the most of them but none of them worked for me unfortunately.
The current iNoBounce and most others that have the scroll locking on y=0 do work scrolling horizontally if y > 0.
|
@himynameisubik hmm, let me know if you can hack any of the code to make it work the way it's expected! PRs welcome. |
Hi, I have a DIV purposely set to scroll horizontally however with iNoBounce it breaks this feature.
You can see the CSS and HTML here.
The text was updated successfully, but these errors were encountered: