metafizzy / flickity

:leaves: Touch, responsive, flickable carousels
https://flickity.metafizzy.co
7.52k stars 605 forks source link

Scroll jump on click in scrollable container #325

Closed xzilja closed 8 years ago

xzilja commented 8 years ago

I am using flickity with only draggable option enabled on desktop (no dots no arrows) and find it bit frustrating when once I focus on an image and drag id browser scrolls to top of that image, I am looking for a way to disable this behaviour if possible.

desandro commented 8 years ago

Thanks for reporting this bug. This behavior was fixed in Flickity v1.1.2. See https://github.com/metafizzy/flickity/issues/76#issuecomment-163035680

Can you reproduce the issue in a reduced test case? Try forking this demo http://codepen.io/desandro/pen/95bd733979aef7484b98d10f47b1685b/

xzilja commented 8 years ago

Thats so strange. I am on 1.1.2, using this through react though, I was not able to replicate issue via codepen, can you please explain in short what your fix for the issue was, I might be able to use it and define my own workaround for it.

Note, I also have multiple instances on one page. and issue only seems to occur in chrome and safari.

desandro commented 8 years ago

See SHA: 33d144eb57872fe8e05e9550884783cfb4a5d643 for the fix

If you have a reduced test case, I can take a look.

desandro commented 8 years ago

Thanks for that. Looks like the issue is that the Flickity gallery is being displayed in an scrollable element, rather than in the browser scroll.

A couple solutions:

accessibility: false

Set [accessibility: false]() in your Flickity options. It disables keyboard accessibility, but fixes the scroll jump issue.

Hack pointerDownFocus

Add this code:

var touchStartEvents = {
  touchstart: true,
  MSPointerDown: true
};

var focusNodes = {
  INPUT: true,
  SELECT: true
};

Flickity.prototype.pointerDownFocus = function( event ) {
  // focus element, if not touch, and its not an input or select
  if ( !this.options.accessibility || touchStartEvents[ event.type ] ||
      focusNodes[ event.target.nodeName ] ) {
    return;
  }
  // hack to fix scroll jump after focus, #76
  var scrollElem = this.options.scrollElement || window;
  var scrollProp = this.options.scrollElement ? 'scrollTop' : 'pageYOffset';
  var prevScrollY = scrollElem[ scrollProp ];

  this.element.focus();
  // reset scroll position after focus
  if ( scrollElem[ scrollProp ] != prevScrollY ) {
    if ( this.options.scrollElement ) {
      scrollElem.scrollTop = prevScrollY;
    } else {
      scrollElem.scrollTo( scrollElem.pageXOffset, prevScrollY );
    }
  }
};

You can then set the scroll element in options

var flkty = new Flickity( elem, {
  scrollElement: document.querySelector('.scroll-container')
})

See demo on CodePen


+1 this issue if you found this helpful. I'm considering adding scrollElement option to Flickity proper.

xzilja commented 8 years ago

accessibility will work for me, thank you. Would be definitely good to see scrollElement feature in the future!

xzilja commented 8 years ago

Hi @desandro returning to this issue as I encountered something that I think is related. Essentially I have actions that append elements to a page or hover of drag and drop item that check scroll state of an element all of these work fine if I place images inside image block, but as soon as I apply flickity they start jumping scroll state up again. I believe this is due to my div with overflow-y: scroll not knowing image height that flickity produces initially? I tried doing .resize() after images onLoad event, but still no luck, wanted to ask if you have any suggestions on how to prevent this behaviour? i.e. prevent this scroll jump.

desandro commented 8 years ago

Sounds an intricate issue. The best way for me to debug this is to put together a reduced test case.

xzilja commented 8 years ago

@desandro I was able to figure it out. I was using flickity with react and initiating it during componentDidMount lifecycle, this didn't work for me and I had to make a work around where I hide image initialy and initiate flickity after image is loaded, so I have it's height after which I show it with flickity already applied.

desandro commented 8 years ago

Looks like this issue hasn't gained any other interest in 4 months. I'm closing it for now. Feel free to chime in if you run into this issue.

franboud commented 5 years ago

I'va run into this issue, and I want to thank you for the accessibility:false fix.