造輪子-輪播

1.最初的思路

當(dāng)前窗口由第一個(gè)變成第二個(gè):先把第二個(gè)放在第一個(gè)的后面南捂,然后第一個(gè)做左滑動(dòng)的動(dòng)畫,第二個(gè)也做向左滑動(dòng)的動(dòng)畫旧找,這樣第二個(gè)就出現(xiàn)在當(dāng)前窗口了溺健,然后把第一個(gè)去掉。
第二個(gè)到第三個(gè)也是一樣的钮蛛,二和三同時(shí)做左滑的動(dòng)畫鞭缭,三就出現(xiàn)在了當(dāng)前窗口,然后去掉二魏颓。
第三個(gè)到第一個(gè):把第一個(gè)放在第三個(gè)的后面岭辣,同時(shí)做左滑的動(dòng)畫,然后干掉第三個(gè)

1.1. 最初的代碼

  • sliders.vue
<template>
    <div class="lf-sliders">
        <div class="lf-sliders-window" ref="window">
            <slot></slot>
        </div>
    </div>
</template>

<script>
    export default {
        name: "LiFaSliders",
    }
</script>

<style scoped>

</style>
  • demo.vue
<template>
    <div>
       <lf-sliders>
           <div class="box">1</div>
           <div class="box">2</div>
           <div class="box">3</div>
       </lf-sliders>
    </div>
</template>

<script>
   import LfSliders from './slides.vue'
    export default {
        name: "demo",
        components: {
            LfSliders
        },
        data(){
            return {

            }
        },
        methods: {

        },
        created() {

        }
    }
</script>

<style scoped>
    .box{
        width: 100px;
        height: 100px;
        background: red;
        border: 1px solid gray;
    }

</style>

我們要讓它其中的一個(gè)顯示琼开,但是我們的組件里只有一個(gè)slot易结,我們?cè)趺茨苤滥膫€(gè)是第一個(gè)?
(1).通過(guò)vue的this.$children來(lái)獲裙窈颉(但是他只能獲取子組件的搞动,而我們當(dāng)前組件沒(méi)有子組件)
(2). dom操作通過(guò)this.$refs.window.children

  • slides.vue
mounted() {
    console.log(this.$children)
    console.log(this.$refs.window.children)
}

我們不想用dom操作,所以需要加一個(gè)子組件lf-sliders-item

1.2. 改進(jìn)后的代碼

  • demo.vue
<template>
    <div>
       <lf-sliders>
           <lf-sliders-item>
               <div class="box">1</div>
           </lf-sliders-item>
           <lf-sliders-item>
               <div class="box">2</div>
           </lf-sliders-item>
           <lf-sliders-item>
               <div class="box">3</div>
           </lf-sliders-item>
       </lf-sliders>
    </div>
</template>
  • slliders-item.vue
<template>
    <div class="lf-sliders-item">
        <slot></slot>
    </div>
</template>

我們需要給每一個(gè)item一個(gè)屬性visible來(lái)控制它是否顯示渣刷,正常情況下我們應(yīng)該在sliders里傳入一個(gè)visible鹦肿,然后在item中通過(guò)props接受這個(gè)visible,但是我們sliders里面用的是slot沒(méi)有l(wèi)f-sliders-item標(biāo)簽辅柴,所以我們沒(méi)法在item中通過(guò)props接收這個(gè)visible箩溃,只能在item里的data中傳入一個(gè)visible

  • lf-sliders-item
<template>
    <div class="lf-sliders-item" v-if="visible">
        <slot></slot>
    </div>
</template>

<script>
    export default {
        name: "sliders-item",
        data(){
            return {
                visible: false
            }
        }
    }
</script>
  • sliders.vue
<template>
    <div class="lf-sliders">
        <div class="lf-sliders-window" ref="window">
            <slot></slot>
        </div>
    </div>
</template>

<script>
    export default {
        name: "LiFaSliders",
        mounted() {
            let first = this.$children[0]
            first.visible = true
        }
    }
</script>
1.3. 簡(jiǎn)單的實(shí)現(xiàn)從1到2的過(guò)程

注意:因?yàn)槲覀儼岩婚_(kāi)始進(jìn)入前的位置設(shè)為了100%,而如果我們不給item絕對(duì)定位的話碌嘀,由于第二張本來(lái)就在第一個(gè)后面涣旨,所以你再加上一開(kāi)始的100%中間就會(huì)有一張的空白,但是如果我們都絕對(duì)定位的話股冗,外層就會(huì)沒(méi)有高度霹陡,所以我們必須至少保證有一個(gè)不絕對(duì)定位,又因?yàn)檩啿ナ窍犬?dāng)前這張離開(kāi)止状,然后才后面的進(jìn)來(lái)烹棉,所以我們需要設(shè)置離開(kāi)的時(shí)候那一張絕對(duì)定位

  • slides.vue
<template>
    <div class="lf-slides">
        <div class="lf-slides-window" ref="window">
            <div class="lf-slides-wrapper">
                <slot></slot>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        name: "LiFaslides",
        mounted() {
            let first = this.$children[0]
            let second = this.$children[1]
            first.visible = true
            setTimeout(()=>{
                first.visible = false
                second.visible = true
            },3000)
        }
    }
</script>

<style scoped lang="scss">
.lf-slides{
    display: inline-block;
    border: 1px solid black;
    &-wrapper{
        position: relative;
        display: flex;
    }
}
</style>
  • slides-item.vue
<template>
    <transition name="fade">
        <div class="lf-slides-item" v-if="visible">
            <slot></slot>
        </div>
    </transition>
</template>

<script>
    export default {
        name: "slides-item",
        data() {
            return {
                visible: false
            }
        }
    }
</script>

<style scoped lang="scss">

    .fade-enter-active, .fade-leave-active {
        transition: all .3s;
    }

    .fade-enter {
        transform: translateX(100%);
    }
    //保證有一個(gè)不絕對(duì)定位,可以讓父級(jí)有寬高
    .fade-leave-active{
        position: absolute;
        left: 0;
        top: 0;
    }

    .fade-leave-to {
        transform: translateX(-100%);
    }
</style>
基本實(shí)現(xiàn)輪播

給sliders傳入一個(gè)selected和給item傳入一個(gè)name怯疤,selected的值就是item的name浆洗,對(duì)應(yīng)的就是哪個(gè)先顯示,這個(gè)selected還得通知到每個(gè)item組件集峦,因此每個(gè)item還需要聲明一個(gè)selected济舆,默認(rèn)為undefined,在sliders中通過(guò)mounted遍歷到每個(gè)item組件讓他們的selected等于sliders里的selected,如果沒(méi)傳就等于item第一個(gè)組件的name,之后我們只需要更新selected就可以被啼,但是因?yàn)閙ounted只能執(zhí)行一次,所以后期我們更新的selected不會(huì)通知到item組件莱革,所以我們需要在sliders中通過(guò)updated事件再次執(zhí)行mounted中的更新selected的方法

  • demo.vue
<template>
    <div>
       <lf-sliders :selected="selected">
           <lf-sliders-item name="1">
               <div class="box">1</div>
           </lf-sliders-item>
           <lf-sliders-item name="2">
               <div class="box">2</div>
           </lf-sliders-item>
           <lf-sliders-item name="3">
               <div class="box">3</div>
           </lf-sliders-item>
       </lf-sliders>
    </div>
</template>

<script>
   import LfSliders from './slides.vue'
   import LfSlidersItem from './sliders-item.vue'
    export default {
        name: "demo",
        components: {
            LfSliders,
            LfSlidersItem
        },
        data(){
            return {
                selected: '1'
            }
        },
        methods: {

        },
        created() {
            let n = 1
            setInterval(()=>{
                n++
                if(n === 4){
                    n = 1
                }
                this.selected = n.toString()
            },3000)
        }
    }
</script>

<style scoped>
    .box{
        width: 100px;
        height: 100px;
        background: red;
        border: 1px solid gray;
    }

</style>
  • slides.vue
<template>
    <div class="lf-slides">
        <div class="lf-slides-window" ref="window">
            <div class="lf-slides-wrapper">
                <slot></slot>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        name: "LiFaslides",
        props: {
            selected: {
                type: String
            }
        },
        mounted() {
            this.updateChildren()
        },
        updated() {
            this.updateChildren()
        },
        methods: {
            updateChildren(){
                let first = this.$children[0]
                this.$children.forEach((vm)=>{
                    vm.selected = this.selected || first.$attrs.name
                })
            }
        }
    }
</script>

<style scoped lang="scss">
.lf-slides{
    display: inline-block;
    border: 1px solid black;
    &-wrapper{
        position: relative;
        display: flex;
    }
}
</style>
  • slides-item.vue
<template>
    <transition name="fade">
        <div class="lf-slides-item" v-if="visible">
            <slot></slot>
        </div>
    </transition>
</template>

<script>
    export default {
        name: "slides-item",
        data() {
            return {
                selected: undefined
            }
        },
        props: {
          name: {
              type: String,
              required: true
          }
        },
        computed: {
            visible(){
                return this.selected === this.name
            }
        }
    }
</script>

<style scoped lang="scss">

    .fade-enter-active, .fade-leave-active {
        transition: all .3s;
    }

    .fade-enter {
        transform: translateX(100%);
    }
    .fade-leave-active{
        position: absolute;
    }

    .fade-leave-to {
        transform: translateX(-100%);
    }
</style>
向左滑動(dòng)實(shí)現(xiàn)

思路:給slides傳入一個(gè)autoPlay屬性果录,默認(rèn)為true,然后將上面的setTImeout放到slides組件中妨马,定義一個(gè)automaticPlay方法挺举,在這個(gè)方法里通過(guò)遍歷子組件拿到一個(gè)names數(shù)組,然后從names數(shù)組里找當(dāng)前的selected是第幾個(gè)烘跺,之后觸發(fā)父組件的update:selected事件湘纵,將names[index]傳給父組件,然后對(duì)index進(jìn)行++滤淳,之后通過(guò)setTimout反復(fù)的調(diào)用

  • slides.vue
export default {
        name: "LiFaslides",
        props: {
            selected: {
                type: String
            },
            autoPlay: {
                type: Boolean,
                default: true
            }
        },
        mounted() {
            this.updateChildren()
            this.automaticPlay()
        },
        updated() {
            this.updateChildren()
        },
        methods: {
            updateChildren(){
                let selected = this.getSelected()
                this.$children.forEach((vm)=>{
                    vm.selected = selected
                })
            },
            automaticPlay(){
                let names = this.$children.map((vm)=>{
                    return vm.name
                })
                let selected = this.getSelected()
                //拿到每一次的索引值梧喷,下次動(dòng)畫好在基礎(chǔ)上累加
                let index = names.indexOf(selected)
                let run = ()=>{
                    this.$emit('update:selected',names[index])
                    index++
                    if(index > names.length-1){
                        index = 0
                    }
                    setTimeout(()=>{
                        run()
                    },3000)
                }
                run()
            },
            getSelected(){
                let first = this.$children[0]
                return this.selected || first.$attrs.name
            }
        }
    }
反向滾動(dòng)

只需要將index++改成--,但是如果直接用--names[index]就會(huì)出問(wèn)題脖咐,所以需要一開(kāi)始的時(shí)候?qū)ndex進(jìn)行判斷铺敌,讓newindex=index-1,如果newindex小于
0就讓它等于最后一個(gè)也就是names.length-1如果大于等于names.length就讓它等于0屁擅,然后每次觸發(fā)update:selected更新的時(shí)候都觸發(fā)一個(gè)select偿凭,把當(dāng)前的index傳入,然后通過(guò)select的時(shí)候拿到當(dāng)前的現(xiàn)在選中的index給lastSelectedIndex屬性(這里還包括點(diǎn)擊某一個(gè)控制點(diǎn)派歌,點(diǎn)擊觸發(fā)select的時(shí)候先把當(dāng)前的selected給lastSelectedIndex弯囊,然后再更新selected為你點(diǎn)擊的那個(gè)點(diǎn)的索引和值),接著觸發(fā)update把最新的index傳進(jìn)去胶果,通過(guò)對(duì)比lastSelectedIndex和selectedIndex來(lái)確定是否給item添加一個(gè)reverse的類

  • sides.vue
<ul class="dots">
            <li v-for="n in childrenLength" :class="{active: selectedIndex === n-1}"
            @click="select(n-1)"
            >
                {{n-1}}
            </li>
        </ul>
export default {
        name: "LiFaslides",
        props: {
            selected: {
                type: String
            },
            autoPlay: {
                type: Boolean,
                default: true
            }
        },
        data(){
          return {
              childrenLength: 0,
              lastSelectedIndex: undefined
          }
        },
        mounted() {
            this.childrenLength = this.$children.length
            this.updateChildren()
            this.automaticPlay()
        },
        updated() {
            this.updateChildren()
        },
        computed: {
          selectedIndex(){
              return this.names.indexOf(this.selected) || 0
          },
          names(){
              return this.$children.map(vm=>vm.name)
          }
        },
        methods: {
            updateChildren(){
                let selected = this.getSelected()
                this.$children.forEach((vm)=>{
                    vm.selected = selected
                    vm.reverse = this.selectedIndex > this.lastSelectedIndex ? false : true
                })
            },
            automaticPlay(){
                let selected = this.getSelected()
                //拿到每一次的索引值匾嘱,下次動(dòng)畫好在基礎(chǔ)上累加
                let index = this.names.indexOf(selected)
                let run = ()=>{
                    let newIndex = index -1
                    if(newIndex < 0){
                        newIndex = this.names.length - 1
                    }
                    if(newIndex === this.names.length){
                        newIndex = 0
                    }
                    this.select(newIndex)
                    setTimeout(()=>{
                        run()
                    },3000)
                }
                setTimeout(run, 3000)
            },
            getSelected(){
                let first = this.$children[0]
                return this.selected || first.$attrs.name
            },
            select(index){
                //當(dāng)選中新的index的時(shí)候,就把舊的index賦給lastSelectedIndex
                this.lastSelectedIndex = this.selectedIndex
                //然后把新的index和選中值傳給selected
                this.$emit('update:selected',this.names[index])
            }
        }
    }
  • sides-item.vue
<template>
    <transition name="fade">
        <div class="lf-slides-item" v-if="visible" :class="{reverse}">
            <slot></slot>
        </div>
    </transition>
</template>

<script>
    export default {
        name: "slides-item",
        data() {
            return {
                selected: undefined,
                reverse: false
            }
        },
        props: {
          name: {
              type: String,
              required: true
          }
        },
        computed: {
            visible(){
                return this.selected === this.name
            }
        }
    }
</script>
<style scoped lang="scss">
    .lf-slides-item{
        width: 100%;
    }
    .fade-enter-active, .fade-leave-active {
        transition: all 1s;
    }

    .fade-enter {
        transform: translateX(100%);
    }
    .fade-enter.reverse{
        transform: translateX(-100%);
    }
    .fade-leave-active{
        position: absolute;
    }

    .fade-leave-to {
        transform: translateX(-100%);
    }
    .fade-leave-to.reverse{
        transform: translateX(100%);
    }
</style>
解決動(dòng)畫混亂的bug

上次的代碼中早抠,會(huì)發(fā)現(xiàn)不管讓它正向還是反向他最后類里都會(huì)有一個(gè)reverse霎烙,所以就會(huì)造成正向的時(shí)候同時(shí)出現(xiàn)正向和反向的動(dòng)畫,之所以會(huì)一直有這個(gè)reverse的類存在是因?yàn)槲覀冊(cè)趗pdateChildren中雖然立即把reverse改了贝或,但是不代表它會(huì)立即生效在dom上面吼过,他有可能是放在了一個(gè)任務(wù)隊(duì)列里。解決辦法:在reverse生效后再去更改當(dāng)前顯示的selected咪奖,也就是延遲更改(在下一次的時(shí)候更改)通過(guò)nextTick就可以

  • slides.vue
updateChildren(){
    let selected = this.getSelected()
    this.$children.forEach((vm)=>{
        vm.reverse = this.selectedIndex > this.lastSelectedIndex ? false : true
        this.$nextTick(()=>{
            vm.selected = selected
        })
    })
},
解決每次只滾動(dòng)顯示兩張圖的bug

在自動(dòng)播放的方法里通過(guò)console發(fā)現(xiàn)index每次都是初始值盗忱,比如初始值是1,那么每次都是1羊赵,所以圖片只顯示兩張趟佃,我們需要每次setTimout的時(shí)候index的值都要變化扇谣,可以在結(jié)束的時(shí)候讓index = newIndex

automaticPlay(){
    let selected = this.getSelected()
    //拿到初始的索引值
    let index = this.names.indexOf(selected)
    let run = ()=>{
        let newIndex = index -1
        if(newIndex < 0){
            newIndex = this.names.length - 1
        }
        if(newIndex === this.names.length){
            newIndex = 0
        }
        index = newIndex
        this.select(newIndex)
        setTimeout(()=>{
            run()
        },3000)
    }
    setTimeout(run, 3000)
},
實(shí)現(xiàn)鼠標(biāo)經(jīng)過(guò)輪播圖,輪播暫停闲昭,離開(kāi)繼續(xù)

思路:給外層加一個(gè)mouseenter和mouseleave監(jiān)聽(tīng)事件罐寨,然后加一個(gè)timerId屬性,讓setTimeout等于它序矩,鼠標(biāo)經(jīng)過(guò)清除setTImoue并把timeId置為null鸯绿,鼠標(biāo)離開(kāi)再次執(zhí)行自動(dòng)滾動(dòng)方法

  • slides.vue
<div class="lf-slides-window" ref="window" @mouseenter="onMouseEnter"
        @mouseleave="onMouseLeave"
        >

methods: {
  onMouseEnter(){
                this.pause()
            },
            onMouseLeave(){
              this.automaticPlay()
            },
            pause(){
              window.clearTimeout(this.timerId)
              this.timerId = null
            },
  autoMaticPlay(){
    +//如果當(dāng)前正在輪播中就不再次執(zhí)行這個(gè)方法
    +           if(this.timerId){
    +               return
                }
   }
}
解決反向的時(shí)候從第一張到最后一張動(dòng)畫是正向動(dòng)畫的問(wèn)題

方法:只需要在上一個(gè)選中的index等于0并且當(dāng)前選中的是最后一個(gè)的索引(this.names.length-1)的情況下讓item的reverse屬性為true就可以

updateChildren(){
    let selected = this.getSelected()
    this.$children.forEach((vm)=>{
        vm.reverse = this.selectedIndex > this.lastSelectedIndex ? false : true
//如果上一張是第一張,當(dāng)前這張是最后一張(也就是反向動(dòng)畫的時(shí)候)就讓它依然是反向動(dòng)畫
+        if(this.lastSelectedIndex === 0 && this.selectedIndex === this.names.length-1){
+            vm.reverse = true
+        }
//如果上一張是最后一張簸淀,當(dāng)前這張是第一張(也就是正向動(dòng)畫的時(shí)候)就讓它依然是正向
+        if(this.lastSelectedIndex === this.names.length-1 && this.selectedIndex === 0){
+           vm.reverse = false
+       }
        this.$nextTick(()=>{
            vm.selected = selected
        })
    })
},

點(diǎn)擊的時(shí)候動(dòng)畫方向不對(duì)
針對(duì)上面的代碼自動(dòng)滾動(dòng)的時(shí)候動(dòng)畫都是正常的瓶蝴,但是當(dāng)我們點(diǎn)擊的下面的對(duì)應(yīng)點(diǎn)的時(shí)候,比如我正向的時(shí)候當(dāng)前顯示的是第一個(gè)租幕,我點(diǎn)第三個(gè)就會(huì)發(fā)現(xiàn)動(dòng)畫是反向的舷手,這就是因?yàn)槲覀兩厦孀龅呐袛啵晕覀円堰@個(gè)判斷加到自動(dòng)滾動(dòng)的方法中去

//如果是自動(dòng)滾動(dòng)的情況下
+ if(this.timerId){
    //如果上一張是第一張劲绪,當(dāng)前這張是最后一張(也就是反向動(dòng)畫的時(shí)候)就讓它依然是反向動(dòng)畫
    if(this.lastSelectedIndex === 0 && this.selectedIndex === this.names.length-1){
        vm.reverse = true
    }
    //如果上一張是最后一張男窟,當(dāng)前這張是第一張(也就是正向動(dòng)畫的時(shí)候)就讓它依然是正向
    if(this.lastSelectedIndex === this.names.length-1 && this.selectedIndex === 0){
        vm.reverse = false
    }
+ }

手機(jī)上觸摸滑動(dòng)
  1. 為什么獲取滑動(dòng)點(diǎn)的坐標(biāo)用的是e.touches[0]而不是e.touch
    答:因?yàn)榇嬖诙帱c(diǎn)觸控e.touches獲取的是用戶手指的數(shù)量,也就是屏幕觸摸點(diǎn)的數(shù)量贾富,e.touches[0]獲取的就是第一個(gè)觸摸點(diǎn)(也就是第一個(gè)手指)歉眷,所以我們需要判斷如果觸摸點(diǎn)的個(gè)數(shù)大于1(有一個(gè)以上的手指觸摸)就直接return
  2. 如何確定是往左滑動(dòng)還是往右滑動(dòng)?
    只需通過(guò)touchstart時(shí)獲取e.touches[0]的clientX和touchEnd的時(shí)候changedTouches[0]的clientX祷安,將開(kāi)始點(diǎn)的clientX通過(guò)一個(gè)屬性存下來(lái)姥芥,然后比較兩者的大小,如果結(jié)束的時(shí)候的距離汇鞭,大于開(kāi)始的時(shí)候就是右滑了凉唐,否則就是左滑,然后分別對(duì)應(yīng)著讓當(dāng)前選中的index加1或減1
  • slides.vue
<div class="lf-slides-window" ref="window" @touchstart="onTouchStart"
             @touchmove="onTouchMove" @touchend="onTouchEnd"
        >
methods: {
onTouchStart(e){
    if(e.touches.length > 0){return}
    this.touchStart = {clientX:e.touches[0].clientX,clientY:e.touches[0].clientY}
    this.pause()
},
onTouchMove(e){
    console.log(e)
},
onTouchEnd(e){
    let {clientX,clientY} = e.changedTouches[0]
    if(clientX > this.touchStart.clientX){
        this.select(this.selectedIndex + 1)
    }else{
        this.select(this.selectedIndex - 1)
    }
    this.automaticPlay()
},
select(newIndex){
    if(newIndex < 0){
        newIndex = this.names.length - 1
    }
    if(newIndex >= this.names.length){
        newIndex = 0
    }
    //讓newIndex等于條件內(nèi)的newIndex
    this.newIndex = newIndex
    //當(dāng)選中新的index的時(shí)候霍骄,就把舊的index賦給lastSelectedIndex
    this.lastSelectedIndex = this.selectedIndex
    //然后把新的index和選中值傳給selected
    this.$emit('update:selected',this.names[newIndex])
},
automaticPlay(){
    //如果當(dāng)前正在輪播中就不再次執(zhí)行這個(gè)方法
    if(this.timerId){
        return
    }
    let selected = this.getSelected()
    //拿到初始的索引值
    let index = this.names.indexOf(selected)
    let run = ()=>{
        this.newIndex = index +1
        this.select(this.newIndex)
        index = this.newIndex
        this.timerId =setTimeout(()=>{
            run()
        },3000)
    }
    this.timerId = setTimeout(run, 3000)
},
}

上面的代碼雖然已經(jīng)實(shí)現(xiàn)了左右滑動(dòng)台囱,但是如果我沒(méi)有左右滑,我是上下滑了(上下翻頁(yè))读整,他依然會(huì)根據(jù)你最后clientX的偏移倆執(zhí)行左滑或右滑時(shí)的函數(shù)

比如根據(jù)上圖我們明顯能知道第二張是翻頁(yè)簿训,第三個(gè)是滑動(dòng),而第一個(gè)我們可以根據(jù)我們自己的設(shè)定米间,比如開(kāi)始和結(jié)束后的角度如果小于三十度就是在滑動(dòng)强品,否則就是翻頁(yè),而角度的確定我們可以根據(jù)三十度直角三角形特性屈糊,三十度角所對(duì)的直角邊是斜邊的一半的榛,所以針對(duì)下圖只要是斜邊除以垂直的直角邊大于2就說(shuō)明是小于三十度,再讓他執(zhí)行左滑右滑的方法

上圖2x那條邊的距離就是

垂直的直角邊的距離就是|y2-y1|

onTouchEnd(e){
    let {clientX,clientY} = e.changedTouches[0]
+    let [x1,y1] = [this.touchStart.clientX,this.touchStart.clientY]
+    let [x2,y2] = [clientX,clientY]
+    let distance = Math.sqrt(Math.pow(x2 - x1,2) + Math.pow(y2 - y1,2))
+    let deltaY = Math.abs(y2-y1)
+    let rate = distance / deltaY
+    if(rate > 2){
        if(clientX > this.touchStart && this.touchStart.clientX){
            this.select(this.selectedIndex - 1)
        }else{
            this.select(this.selectedIndex + 1)
        }
+    }
    this.automaticPlay()
},

添加單元測(cè)試

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逻锐,一起剝皮案震驚了整個(gè)濱河市夫晌,隨后出現(xiàn)的幾起案子雕薪,更是在濱河造成了極大的恐慌,老刑警劉巖晓淀,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件所袁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡凶掰,警方通過(guò)查閱死者的電腦和手機(jī)燥爷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)锄俄,“玉大人局劲,你說(shuō)我怎么就攤上這事勺拣∧淘” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵毅戈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我愤惰,道長(zhǎng),這世上最難降的妖魔是什么宦言? 我笑而不...
    開(kāi)封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮奠旺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘响疚。我一直安慰自己,他們只是感情好忿晕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布装诡。 她就那樣靜靜地躺著,像睡著了一般践盼。 火紅的嫁衣襯著肌膚如雪鸦采。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天咕幻,我揣著相機(jī)與錄音渔伯,去河邊找鬼。 笑死谅河,一個(gè)胖子當(dāng)著我的面吹牛咱旱,可吹牛的內(nèi)容都是我干的确丢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吐限,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鲜侥!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起诸典,我...
    開(kāi)封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤描函,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后狐粱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體舀寓,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年肌蜻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了互墓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蒋搜,死狀恐怖篡撵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情豆挽,我是刑警寧澤育谬,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站帮哈,受9級(jí)特大地震影響膛檀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜娘侍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望私蕾。 院中可真熱鬧,春花似錦踩叭、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)满力。三九已至轻纪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刻帚,已是汗流浹背涩嚣。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留顷歌,地道東北人幔睬。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓溪窒,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親澈蚌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宛瞄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 目前市場(chǎng)上的APP中交胚,輪播圖可以說(shuō)是很常見(jiàn)的。一個(gè)好的輪播圖杯活,基本上適用于所有的APP熬词。是時(shí)候打造一個(gè)自己的...
    帶心情去旅行閱讀 17,309評(píng)論 15 93
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容歪今。關(guān)于...
    云之外閱讀 5,050評(píng)論 0 29
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,214評(píng)論 0 6
  • 在使用 Vue 之后寄猩,寫了兩個(gè)版本的輪播骑疆,一個(gè)版本利用 Vue 的動(dòng)畫很輕松地寫出了無(wú)縫輪播替废,但是由于 flex ...
    靈魂治愈閱讀 693評(píng)論 0 13
  • 主要還是自己看的舶担,所有內(nèi)容來(lái)自官方文檔。 介紹 Vue.js 是什么 Vue (讀音 /vju?/衣陶,類似于 vie...
    Leonzai閱讀 3,353評(píng)論 0 25