metafizzy / flickity

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

Detect direction #887

Closed richgcook closed 5 years ago

richgcook commented 5 years ago

Is it possible to tell whether the user went back or forward (previous or next) when using flkty.on('select')?

https://github.com/metafizzy/flickity/issues/866#issuecomment-440679048

This was useful but only if wrapped is turned off...

richgcook commented 5 years ago

I can work out the prev/next index but unsure, upon select, how to determine if the user went back or forward.

flkty.on('select', function(index) {

    var previousIndex = fizzyUIUtils.modulo(this.selectedIndex - 1, this.slides.length),
        nextIndex = fizzyUIUtils.modulo(this.selectedIndex + 1, this.slides.length);

    console.log('previousIndex: ' + previousIndex);
    console.log('index: ' + index);
    console.log('nextIndex: ' + nextIndex);
});
richgcook commented 5 years ago

I believe this solves it...

if (selectedIndex !== 0 || flkty.selectedIndex !== 0) {

    if (selectedIndex > flkty.selectedIndex && (selectedIndex != (slideCount - 1))) {
        console.log('User moved backwards');
        clickCount = mediaCount;
    } else if (selectedIndex == 0 && flkty.selectedIndex == (slideCount - 1)) {
        console.log('User moved backwards');
        clickCount = mediaCount;
    } else if (selectedIndex == (slideCount - 1) && flkty.selectedIndex == (slideCount - 1)) {
        console.log('User moved backwards');
        clickCount = mediaCount;
    } else if (selectedIndex == (slideCount - 1) && flkty.selectedIndex == (slideCount - 2)) {
        console.log('User moved backwards');
        clickCount = mediaCount;
    } else if (selectedIndex == (slideCount - 2) && flkty.selectedIndex == (slideCount - 2)) {
        console.log('User moved backwards');
        clickCount = mediaCount;
    } else {
        console.log('User moved forwards');
    }

}

if (flkty.selectedIndex != selectedIndex) {
    selectedIndex = flkty.selectedIndex;
}
desandro commented 5 years ago

Looks like that previous demo had a typo. Try this code

var $carousel = $('.carousel').flickity({
  wrapAround: true,
});

var flkty = $carousel.data('flickity');
var previousIndex = flkty.selectedIndex;

$carousel.on( 'change.flickity', function( event, index ) {
  // get changed index
  var delta = index - previousIndex;
  var lastIndex = flkty.slides.length - 1;
  if ( previousIndex == lastIndex && index === 0 ) {
    console.log('wrapped forward');
  } else if ( previousIndex === 0 && index == lastIndex ) {
    console.log('wrapped back')
  } else if ( delta > 0 ) {
    console.log( 'moved forward', delta )
  } else {
    console.log( 'moved back', delta )
  }

  previousIndex = index;
});

See demo https://codepen.io/desandro/pen/210fff0fe5ad25676b16755f30c7354b

richgcook commented 5 years ago

@desandro Thanks for the tidy up ;)

richgcook commented 5 years ago

This only seems to work with 3 or more slides... it doesn't work if there's only 2. Is that correct?

desandro commented 5 years ago

You could try to read flkty.velocity to see how the slider is moving.

I'll leave that solution up to you.