Skip to content
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

afterChange is not triggered when adaptiveHeight is true #1262

Open
Drafter500 opened this issue Jun 7, 2018 · 14 comments · May be fixed by #1954
Open

afterChange is not triggered when adaptiveHeight is true #1262

Drafter500 opened this issue Jun 7, 2018 · 14 comments · May be fixed by #1954

Comments

@Drafter500
Copy link

https://codesandbox.io/s/k6n066ox5

@Drafter500 Drafter500 reopened this Jun 7, 2018
@yunyong
Copy link

yunyong commented Jun 12, 2018

So I changed it to "beforeChange()"
:(

@clairefritz
Copy link

Same issue here!

@jeremiah-s-eldridge
Copy link

I saw this before adding adaptiveHeight = true. My slides can have variable heights, and if the height of the img element changes the afterChange event fails to dispatch. If you add adaptiveHeight=true, it gets exponentially worse.

@jeremiah-s-eldridge
Copy link

it looks like the animationEndCallback is never executed under these conditions - haven't found where it should be executed from yet

@martinek
Copy link

martinek commented Oct 9, 2018

So I figured out why this happen in our case.

We use beforeChange and afterChange to disable clicking on items while swiping. In our case, when you swipe, sometimes beforeChange would be called but afterChange would not be called. This would stuck wrapper in "sliding" state with disabled clicks.

What happens in library is that when slide is moved, slider height is changed to accomodate for higher/shorter slide height, this triggers window resize (in our case) and resizeWindow callback which clears this.animationEndCallback which causes afterChange to not fire at all.

I'm not sure how to fix this as I'm not sure why animationEndCallback is being reset. There is some comment about autoplay, not sure how that work.

@janhesters
Copy link

janhesters commented Nov 8, 2018

Oh wow I struggled with this for about an hour before I stumbled upon this thread. After reading this, let me share with you the workaround I used:

const speed: number = 500;
const settings: Settings = {
  adaptiveHeight: true,
  // NOTE: afterChange is broken when adaptiveHeight is set to true. See:
  // https://github.com/akiran/react-slick/issues/1262. Therefoe this hacky solution.
  beforeChange: (current, next) =>
    setTimeout(() => this.setState(prevState => ({ ...prevState, currentSlide: next })), speed),
  speed
};

@epignosisx
Copy link

epignosisx commented Nov 13, 2018

I debugged the issue a little bit and the problem is that the callback to this timeout:

this.animationEndCallback = setTimeout(() => {

is not executing because during the wait period resizeWindow is being called and it clears the timeout:

clearTimeout(this.animationEndCallback);
delete this.animationEndCallback;

The resizeWindow method is triggered by the resizeObserver:

this.onWindowResized(false); // don't set trackStyle hence don't break animation

@tchamblee
Copy link

Here's what worked for me, just include this in your settings object:

const speed = 500
const settings = {
  beforeChange: (current, next) => {
    setTimeout(afterChange(next), speed)
  },
  speed
}

@sjovall
Copy link

sjovall commented Jan 30, 2019

Damn... took me a while to figure this out.

Is anyone working on a proper solution to this issue?

Btw, this only seems to be a problem in cases where custom buttons are used for the navigation that utilizes the next / prev methods. The default buttons provided by the slider works fine even if adaptiveHeight is being used.

Here's my own sandbox if anyone is interested https://codesandbox.io/s/mykn4lq78j.

@alex-lechner
Copy link

Any update on this issue? The workaround does not work for me.

@alex-lechner
Copy link

So I've found a workaround now. The slider in my application needs to keep track of the slider's dragging state because whether the user swipes or not depends on if the item in the slider is clickable. The items are only clickable if the user does not swipe.
Here's my code:

constructor(props, context) {
    super(props, context);
    // set states in constructor
    this.state = {
      dragging: false,
      hasAdaptiveHeight: true
    };
}

render() {
    const settings = {
      adaptiveHeight: this.state.hasAdaptiveHeight,
      beforeChange: (current, next) => {
        this.setState({ dragging: true }, () => {
          if (this.state.hasAdaptiveHeight) {
            setTimeout(() => {
              this.setState({ dragging: false });
            }, 1000);
          }
        });
      },
      afterChange: next => {
        // this is only called if adaptiveHeight is set to false
        this.setState({ dragging: false });
      }
    }

    return (
      <Slider {...settings}>
        // your items here
      </Slider>
    );
}

@PotLid
Copy link

PotLid commented Apr 23, 2019

Oh wow I struggled with this for about an hour before I stumbled upon this thread. After reading this, let me share with you the workaround I used:

const speed: number = 500;
const settings: Settings = {
  adaptiveHeight: true,
  // NOTE: afterChange is broken when adaptiveHeight is set to true. See:
  // https://github.com/akiran/react-slick/issues/1262. Therefoe this hacky solution.
  beforeChange: (current, next) =>
    setTimeout(() => this.setState(prevState => ({ ...prevState, currentSlide: next })), speed),
  speed
};

This work arounds perfectly works on me, thanks :)

metzgegu added a commit to tracim/tracim that referenced this issue Nov 28, 2019
@GuyPaddock
Copy link

We just ran into this, especially on Safari 13. In our case, we're not using adaptiveHeight but changes in the slider coincide with changes in flow elsewhere on the page (e.g. we're using the slider as a timeline component, below which other content appears based on what slide of the timeline is selected). afterChange does not get called consistently, and adding debug print statements to react-slider, I can confirm that clearTimeout(_this.animationEndCallback) being called from windowResize is happening precisely at the times that the afterChange callback is being dropped.

So, perhaps a better title for this issue should be that "afterChange does not get called if slider animation causes page dimensions to change".

@fabianrichter
Copy link

Oh wow I struggled with this for about an hour before I stumbled upon this thread. After reading this, let me share with you the workaround I used:

const speed: number = 500;
const settings: Settings = {
  adaptiveHeight: true,
  // NOTE: afterChange is broken when adaptiveHeight is set to true. See:
  // https://github.com/akiran/react-slick/issues/1262. Therefoe this hacky solution.
  beforeChange: (current, next) =>
    setTimeout(() => this.setState(prevState => ({ ...prevState, currentSlide: next })), speed),
  speed
};

This does not completely solve the issue as the transition is not working with this approach. Are there any updates on this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.