实现手机端滑动导航条,带有弹性回弹效果

<template>
<div>
<div id="slider" class="mui-slider">
<div id="sliderSegmentedControl" class="mui-scroll-wrapper mui-slider-indicator mui-segmented-control mui-segmented-control-inverted">
<div class="mui-scroll">
<a class="mui-control-item" :class="activeNav === index ? 'mui-active' : ''" v-for="(item,index) in navList" v-bind:key="index" @click="changeActive(index)">
{{item}}
</a>
</div>
</div>
</div>
</div>
</template>

<script>
export default {
data() {
return {
startX: '',
startY: '',
moveEndX: '',
moveEndY: '',
X: '',
Y: '',
muicsroll: undefined,
muislider: undefined,
lastX: 0, //上次所在位置
posX: 0, //最终位置 上次所在位置 + 移动的距离 this.X
navList: [
'推荐',
'热点',
'北京',
'社会',
'娱乐',
'科技',
'财经',
'体育'
],
activeNav: 0
}
},
mounted: function() {
this.muicsroll = document.getElementsByClassName('mui-scroll')[0]
this.muislider = document.getElementsByClassName('mui-slider')[0]
this.scroll()
},
methods: {
scroll: function() {
this.muicsroll.addEventListener('touchstart',this.touch,false)
this.muicsroll.addEventListener('touchmove',this.touch,false)
this.muicsroll.addEventListener('touchend',this.touch,false)
},
touch: function(ev) {
var ev = ev || window.ev
switch(ev.type){
case 'touchstart':
this.startX = ev.touches[0].pageX
this.startY = ev.touches[0].pageY
break;
case 'touchmove':
this.moveEndX = ev.changedTouches[0].pageX
this.moveEndY = ev.changedTouches[0].pageY
this.X = this.moveEndX - this.startX
this.Y = this.moveEndY - this.startY
if ( Math.abs(this.X) > Math.abs(this.Y) && this.X > 0 ) {
this.posX = this.X + this.lastX
this.muicsroll.style.transform = "translate3d("+this.posX+"px,0px,0px)"
this.muicsroll.style.transitionDuration = "0ms"
this.muicsroll.style.transitionTimingFunction = "cubic-bezier(0.165, 0.84, 0.44, 1)"
}
if ( Math.abs(this.X) > Math.abs(this.Y) && this.X < 0 ) {
this.posX = this.X + this.lastX
this.muicsroll.style.transform = "translate3d("+this.posX+"px,0px,0px)"
this.muicsroll.style.transitionDuration = "0ms"
this.muicsroll.style.transitionTimingFunction = "cubic-bezier(0.165, 0.84, 0.44, 1)"
}
break;
case 'touchend':
this.lastX = this.posX
if(this.posX > 0) {
this.muicsroll.style.transitionDuration = "500ms"
this.muicsroll.style.transform = "translate3d(0px,0px,0px)"
this.lastX = 0
}
if(this.posX < -(this.muicsroll.offsetWidth - this.muislider.offsetWidth)) {
this.muicsroll.style.transitionDuration = "500ms"
this.muicsroll.style.transform = "translate3d("+ (-(this.muicsroll.offsetWidth - this.muislider.offsetWidth)) +"px,0px,0px)"
this.lastX = -(this.muicsroll.offsetWidth - this.muislider.offsetWidth)
}
break;
}
},
changeActive: function(index) {
this.activeNav = index
}
}
}
</script>

<style>

</style>

/*
点击切换选中用vue实现
 
通过判断最左侧点所在位置 (上次拖动离开后所在位置 + 本次移动的距离) 来进行定位
动画效果 添加transform  属性 参考mui中所添加的动画代码
*/
 
 
父子组件传递
父组件:
 
<template>
    <div>
        <nav-scroll :navList="navList" v-on:listenEvent="getActiveIndex"></nav-scroll>
    </div>
</template>

<script>
    import navscroll from './NavScroll.vue'
    export default {
        data() {
            return {
                navList: [
                    '推荐',
                    '热点',
                    '北京',
                    '社会',
                    '娱乐',
                    '科技',
                    '财经',
                    '体育'
                ]
            }
        },
        components: {
            'nav-scroll': navscroll
        },
        mounted: function() {

        },
        methods: {
            getActiveIndex: function(data) {
                console.log(data)
            }
        }
    }
</script>

<style>

</style>

 

子组件:

 

<template>
    <div>
        <div id="slider" class="mui-slider">
            <div id="sliderSegmentedControl" class="mui-scroll-wrapper mui-slider-indicator mui-segmented-control mui-segmented-control-inverted">
                <div class="mui-scroll">
                    <a class="mui-control-item" :class="activeNav === index ?  'mui-active' : ''" v-for="(item,index) in navList" v-bind:key="index" @click="changeActive(index)">
                        {{item}}
                    </a>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                startX: '',
                startY: '',
                moveEndX: '',
                moveEndY: '',
                X: '',
                Y: '',
                muicsroll: undefined,
                muislider: undefined,
                lastX: 0,       //上次所在位置
                posX: 0,         //最终位置 上次所在位置 + 移动的距离 this.X 
                activeNav: 0
            }
        },
        props: ["navList"],
        mounted: function() {
            this.muicsroll = document.getElementsByClassName('mui-scroll')[0]
            this.muislider = document.getElementsByClassName('mui-slider')[0]
            this.scroll()
        },
        methods: {
            scroll: function() {
                this.muicsroll.addEventListener('touchstart',this.touch,false)
                this.muicsroll.addEventListener('touchmove',this.touch,false)
                this.muicsroll.addEventListener('touchend',this.touch,false)
            },
            touch: function(ev) {
                var ev = ev || window.ev
                switch(ev.type){
                    case 'touchstart':
                        this.startX = ev.touches[0].pageX
                        this.startY = ev.touches[0].pageY
                    break;
                    case 'touchmove':
                        this.moveEndX = ev.changedTouches[0].pageX
                        this.moveEndY = ev.changedTouches[0].pageY
                        this.X = this.moveEndX - this.startX
                        this.Y = this.moveEndY - this.startY
                        if ( Math.abs(this.X) > Math.abs(this.Y) && this.X > 0 ) {
                            this.posX = this.X + this.lastX
                            this.muicsroll.style.transform = "translate3d("+this.posX+"px,0px,0px)"
                            this.muicsroll.style.transitionDuration = "0ms"
                            this.muicsroll.style.transitionTimingFunction = "cubic-bezier(0.165, 0.84, 0.44, 1)"
                        }
                        if ( Math.abs(this.X) > Math.abs(this.Y) && this.X < 0 ) {
                            this.posX = this.X + this.lastX
                            this.muicsroll.style.transform = "translate3d("+this.posX+"px,0px,0px)"
                            this.muicsroll.style.transitionDuration = "0ms"
                            this.muicsroll.style.transitionTimingFunction = "cubic-bezier(0.165, 0.84, 0.44, 1)"
                        }
                    break;
                    case 'touchend':
                        this.lastX = this.posX
                        if(this.posX > 0) {
                            this.muicsroll.style.transitionDuration = "500ms"
                            this.muicsroll.style.transform = "translate3d(0px,0px,0px)"
                            this.lastX = 0
                        }
                        if(this.posX < -(this.muicsroll.offsetWidth - this.muislider.offsetWidth)) {
                            this.muicsroll.style.transitionDuration = "500ms"
                            this.muicsroll.style.transform = "translate3d("+ (-(this.muicsroll.offsetWidth - this.muislider.offsetWidth)) +"px,0px,0px)"
                            this.lastX = -(this.muicsroll.offsetWidth - this.muislider.offsetWidth)
                        }
                    break;
                } 
            },
            changeActive: function(index) {
                this.activeNav = index
                this.$emit('listenEvent',this.activeNav)
            }
        }
    }
</script>

<style>

</style>

 

 

效果展示

 

 

转载于:https://www.cnblogs.com/suanmei/p/9668595.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用touch事件来实现手机端滑块滑动效果。以下是一个简单的示例代码: HTML: ```html <div class="slider"> <div class="slider-bar"></div> <div class="slider-thumb"></div> </div> ``` CSS: ```css .slider { position: relative; width: 200px; height: 10px; background-color: #ddd; } .slider-bar { position: absolute; top: 50%; left: 0; width: 100%; height: 2px; background-color: #333; transform: translateY(-50%); } .slider-thumb { position: absolute; top: 0; left: 0; width: 20px; height: 20px; background-color: #333; border-radius: 50%; transform: translate(-50%, -50%); cursor: pointer; } ``` JavaScript: ```javascript var slider = document.querySelector('.slider'); var thumb = slider.querySelector('.slider-thumb'); var startX, thumbLeft; thumb.addEventListener('touchstart', function(event) { startX = event.touches[0].clientX; thumbLeft = parseInt(window.getComputedStyle(thumb).left); }); thumb.addEventListener('touchmove', function(event) { event.preventDefault(); var moveX = event.touches[0].clientX - startX; var newLeft = thumbLeft + moveX; if (newLeft < 0) { newLeft = 0; } else if (newLeft > slider.offsetWidth - thumb.offsetWidth) { newLeft = slider.offsetWidth - thumb.offsetWidth; } thumb.style.left = newLeft + 'px'; }); thumb.addEventListener('touchend', function(event) { // do something when thumb is released }); ``` 这个示例代码会创建一个横向的滑块,滑块的宽度是200px,高度是10px。滑块的背景颜色是灰色,滑块条是黑色的。滑块的滑块是一个小圆球,颜色也是黑色的。当滑块被拖动时,滑块的位置会跟着变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值