cubiq / iscroll

Smooth scrolling for the web
http://iscrolljs.com
MIT License
12.88k stars 3.81k forks source link

iScroll and Chrome 55... #1100

Closed hutchski closed 7 years ago

hutchski commented 7 years ago

I am testing using Chrome 55, which, I am reading, Google hopes to release December 6, 2016. When I simulate a mobile device, horizontal scrolling in the carousel is not working right. Instead of smoothly scrolling, it seems to hang and jank along only a few pixels: http://lab.cubiq.org/iscroll5/demos/event-passthrough/ Chrome 54 seems to handle everything fine. Is there a fix or workaround for this?

leuvi commented 7 years ago

me too. but my browser is chrome canary, other do well.

hutchski commented 7 years ago

@leuvi yeah, looks like Canary is showing Chrome v56.

mattixittam commented 7 years ago

iScroll doesn't work correctly with PointerEvents as just implemented in Chrome 55, which also has knock-on effects on other plugins using events. We've disabled the PointerEvents check in our application for now, making iScroll fall back to regular events. This fixes the problem.

xymopen commented 7 years ago

add <script>window.PointerEvent = undefined</script> in <head> could temporarily fix the issue. However at last we will need PointerEvent support.

boaz-amit commented 7 years ago

iScroll has an undocumented disablePointer setting, that can be used to disable the pointer event in a more orderly fashion. Passing disablePointer: true seems to solve the issue in the latest versions of Chrome. Note @toser's comment - this should be used in combination with disableMouse: true , for example.

The following settings appear to work well for us in Chrome 55 for Windows/Android/webview:

    scrollX: false,
    scrollY: true,
    probeType: 1,
    tap: true,
    click: false,
    preventDefaultException: {
        tagName: /.*/
    },
    mouseWheel: true,
    scrollbars: true,
    fadeScrollbars: true,
    interactiveScrollbars: true,
    deceleration: 0.001,
    disableMouse: false,
    disablePointer: true
toser commented 7 years ago

@boaz-amit this is great! Bu you also need to set disableTouch and/or disableMouse to false. Otherwise you may run into a situation where no events are used.

You should basically add these three lines to your options object:

disablePointer: true, // important to disable the pointer events that causes the issues
disableTouch: false, // false if you want the slider to be usable with touch devices
disableMouse: false // false if you want the slider to be usable with a mouse (desktop)
boaz-amit commented 7 years ago

@toser Thanks, good point. In my case, disableMouse: true was already set, so I didn't think about it :)

dingquantracy commented 7 years ago

@boaz-amit thanks, hahaha~~~~

avisarine commented 7 years ago

Hello, Me also experiencing the problem. Vertical scrolling is not working right. Instead of smoothly scrolling, it seems to hang and jank along only a few pixels. (tested on android mobile devices). On System Webview version 54 this scrolling works as expected. On version 55 scrolling stops working.

Does suggested fix (temporarily disable PointerEvents) disable any of the functionality of this plugin (infinite scrolling)? Is there possibility this issue will be fixed by google in System Webview update?

Thank you

earnaz commented 7 years ago

I think the suggested fix (PointerEvent = undefined) does not disable any of the functionality, because before Chrome 55 the PointerEvents object did not exist (by default) [https://www.chromestatus.com/feature/4504699138998272]. Therefore, if your code worked, it should continue to do so.

cleversonviana commented 7 years ago

Those didn't work for me.. Any clue ?

yiannakasgeorge commented 7 years ago

Experiencing the same problems on Android System WebView 55.0.2883.91.

Since the update, scrolling seems to hang and jank along only a few pixels.

The fix below does NOT resolve the issue on our end:

disablePointer: true, // important to disable the pointer events that causes the issues disableTouch: false, // false if you want the slider to be usable with touch devices disableMouse: false // false if you want the slider to be usable with a mouse (desktop)

Any other workaround is greatly appreciated. Thanks.

xymopen commented 7 years ago

@earnaz iScroll has some default value for options, which is in src/core.js. As you can see with utils.hasPointer as true, disablePointer, disableMouse and disableTouch all become true, which prevent iScroll from working. According to line 89 in src/utils.js, utils.hasPointer is simply !!(window.PointerEvent || window.MSPointerEvent). I was in a hurry to get my code work and did't give it another thought. @boaz-amit 's method is much better. However then it will leave you to decide whether use MouseEvent or TouchEvent.

cleversonviana commented 7 years ago

Problem solved.......

if System WebView version is <= 54 iScroll is working ok

as workaround in iscroll.js v 5.2 change the line 298 from disablePointer : !utils.hasPointer, disableTouch : utils.hasPointer || !utils.hasTouch, disableMouse : utils.hasPointer || utils.hasTouch, to disablePointer:true, disableTouch:false, disableMouse:true,

sdilipsam commented 7 years ago

Hi,

I am having issues in Chrome on Windows. The disablePointer: true fix solved the issue in Chrome on Mac.

sculove commented 7 years ago

Chrome 55+ starts to support PointerEvent. if a browser could use PointerEvent, iScroll applys PointerEvent as InputType. But, if touch-action property is default(auto), pointermove event is fired only once!

I think iScroll should apply touch-action property according to directions.

this issue is so serious issue. I will patch this issue soon.

@cubiq could you bump revision number?

sculove commented 7 years ago

ref #1039

jarben commented 7 years ago

Using:

disablePointer: true,
disableTouch: false,
disableMouse: false

solved the issue for me. However, I can't scroll anymore when touchstart starts on the iscroll element:

iscroll

Can be tested at http://datamatic.io using Chrome dev tools..

mustaqahmed commented 7 years ago

What @sculove mentioned above is the right solution here: instead of disabling the pointer event support, please add a CSS property "touch-action: none" to the element that should be scrolled through JS handlers.

For example, the iScroll event-passthrough demo should add "touch-action: none" CSS property to #scroller.

Details: One important difference of PointerEvents from TouchEvents is that a browser touch-action (browser scrolling action in this case) dispatches a "pointercancel" event and then suppresses dispatching of more pointer events while browser is "in change" of the scrolling. Adding "touch-action: none" suppresses browser scrolling, so JS will received all pointer events to handle the scrolling itself.

RByers commented 7 years ago

Rather than fixing the demo (and asking each user to set touch-action themself), perhaps the iScroll JavaScript should be setting scroller.style.touchAction='none' itself? It's really up to the code that's consuming touch events to say what the touch-action should be.

RByers commented 7 years ago

Note that I'd expect all of these sites to already be broken in Edge / IE (which has long had pointer events - we've now just shipped it in Chrome too, and it's coming soon in Firefox). Are there any examples here of something that's working in Edge but broken in Chrome?

RByers commented 7 years ago

From code inspection of core.js, it looks to me like the right fix is something like this (warning: untested):


disable: function () {
  this.wrapper.style.touchAction='';
  this.enabled = false;
},

enable: function () {
  var touchAction = 'none'
  if ( this.options.eventPassthrough == 'vertical' ) {
    touchAction = 'pan-y';
  } else if ( this.options.eventPassthrough == 'horizontal' ) {
    touchAction = 'pan-x';
  }
  this.wrapper.style.touchAction = touchAction;
  if (touchAction != 'none') {
    // add pinch-zoom support if the browser supports it, but if not (eg. Chrome <55) do nothing
    this.wrapper.style.touchAction += ' pinch-zoom';
  }
  this.enabled = true;
},
mustaqahmed commented 7 years ago

Thanks @RByers for suggesting a perfect fix.

Most of the demos work in Edge/IE because they have MS-prefixed CSS property: -ms-touch-action: none; added to the html element. The event-passthrough demo is broken on Edge too because it doesn't have it.

RByers commented 7 years ago

Edge no longer supports -ms-touch-action (only IE does). I checked a bunch of the demos and basically none of them work at all on Edge (but adding touch-action seems to fix them). So any sites relying on iScroll either don't care about Edge users (>5% of usage these days), have disabled iScroll for edge users, or have otherwise hacked-around the bug themselves by adding their own touch-action property (which will also fix it for Chrome).

mustaqahmed commented 7 years ago

The Edge I tested had touch events enabled, sorry. Rick is right, Edge is broken for pointer events.

sculove commented 7 years ago

thank you for @RByers
Could you contribute this issue?

RByers commented 7 years ago

Sorry, I don't have enough experience with iScroll to test that my patch fixes edge cases correctly (nor do I have the time). Hopefully someone with experience contributing to iScroll will test it out and land it.

leuvi commented 7 years ago

@hutchski add style {touch-action: none} to scroller element, perfect!! tks @mustaqahmed demo: http://www.sweetui.com/#/scroller

sculove commented 7 years ago

ref #1118, #1107

boaz-amit commented 7 years ago

@sculove Thanks for all your hard work! Are the recent commits to the build files going to be versioned into a separate release than the current 5.2.0?

sculove commented 7 years ago

@boaz-amit ok. I will add different version name. like this

iscroll v5.2.0-snapshot

but, I do not have permission to upload a version.

Threrefore, you can download following coomand

npm i github:cubiq/iscroll --save
monecchi commented 7 years ago

@toser and @mustaqahmed's settings proposal work together as a solution for me. Thanks!