vue-scrollto icon indicating copy to clipboard operation
vue-scrollto copied to clipboard

cancel repeatedly x scrolling

Open webspecialist opened this issue 5 years ago • 4 comments

I saw a relative question here with that "problem" but it didn't helped me so much.

I am trying to create x scrolling (dynamic) slider. So here is my code working with Nuxt.

`

<div class="container">
  <div id="container" class="aligner slide-out" ref="slider">
    <div class="slide-in" >
      <div class="slide-col-4" v-for="o in myObj" :key="o.id" :ref="'r'+o.id">
        <!-- <button @click="displayRef('r'+o.id, o.id)">
             {{'r'+o.id}}
        </button> -->
      </div>
    </div>
  </div>
  <div class="myslide-btns aligner">
    <div class="the-center">
      <div class="left" @click="clickSlide(1)"><font-awesome-icon :icon="[ 'fas', 'chevron-left' ]" /></div>
      <div class="right" @click="clickSlide(2)" ref="right-arr"><font-awesome-icon :icon="[ 'fas', 'chevron-right' ]" /></div>
    </div>
  </div>
</div>
<script>
export default {
  data(){
      return {
          right: '',
          stopSlide: false,
          myObj: [
            {
              id: 0
            },
            {
              id: 1
            },
            {
              id: 2
            },
            {
              id: 3
            }
          ]
      }
  },
  methods: {
    clickSlide(way) {
      if(this.stopSlide == true){
        return
      }
    let VueScrollTo = require('vue-scrollto');
    let sliderPos = this.$refs.slider.scrollLeft
    let sizebox = (320 + 30)
    let sizeSlider = (320 + 30) * this.myObj.length
    let pos = this.myObj.length
    let afterPos = ((sizeSlider - sliderPos) / sizebox)
    let nextPos = pos - afterPos
    let nextDest = 0
    console.log(sliderPos)
      let prevDest = 0
      if(way == 2){
        nextDest = 1+Math.floor(nextPos)
        prevDest = Math.round(nextPos)
      }else{
        nextDest = -1 + Math.floor(nextPos)
        prevDest = Math.floor(nextPos)
      }
      console.log(prevDest)
      console.log(nextDest)
      if(nextDest < 0 && way == 1){
        return
      }
      let repeat = 0
      let element = this.$refs['r'+nextDest.toString()][0]
      let duration = 500
      
      let options = {
          container: '#container',
          easing: 'ease-in-out',
          offset: -20,
          force: true,
          cancelable: true,
          myThis: this,
          onStart: function(element) {
            // scrolling started
            console.log('start')
            console.log()
            options.myThis.turnTrue()
          },
          onDone: function(element) {
            console.log('done')
            options.myThis.turnTrue()
          },
          onCancel: function() {
            console.log('stop')
          },
          x: true,
          y: false
      }
      
        let cancelScroll = this.$scrollTo(element, duration, options)
      
      if(this.stopSlide == true){
        cancelScroll()
      }
    },
    turnTrue(){
      return this.stopSlide == true
    },
    turnFalse(){
      return this.stopSlide = false
    }
  }
}
</script>

The problem is when I repeatedly trying to click ex. the next button the animation flickers. If someone hit the button multiple times, I want to stop the scrolling if the transition is not completed.

How to do that?

webspecialist avatar Mar 25 '19 11:03 webspecialist

Could you provide a link to a codesandbox or a jsfiddle?

Generally, you have 2 ways of handling it, if the scroller is scrolling, prevent any clicks until the scrolling is finished. To do this one, in onStart set a flag like this.isCurrentlyScrolling = true and in onDone set this.isCurrentlyScrolling = false. In clickSlide you can then if(this.isCurrentlyScrolling) return to prevent action.

The other way would be to cancel the current scroll, and then start a new one to the desired element. That would be similar, you'd have to store the last scroll cancel function, for example this.cancel = this.$scrollTo(...), then in onDone set this.cancel = false and in your clickSlide check if cancel is truthy if(this.cancel) this.cancel() and don't return. This way might not look smooth though, I haven't tried it in action...

rigor789 avatar Mar 25 '19 12:03 rigor789

Hi I tried to create my (short) code in the codesandbox.

Here is the link: https://codesandbox.io/s/pj9mz3r5o7

Now I have a problem it didn't recognize the scroll to.

webspecialist avatar Mar 25 '19 19:03 webspecialist

@webspecialist I think the project is a Nuxt project, and I'm not really familiar with it - could you add it to a basic vue project? (https://codesandbox.io/s/vue)

rigor789 avatar Mar 25 '19 21:03 rigor789

https://codesandbox.io/s/1zkl605p47 Here is as a Vue project but I dont know how to set the let VueScrollTo = require("vue-scrollto");

webspecialist avatar Mar 30 '19 11:03 webspecialist