当前位置: 首页 > Web前端 > HTML

vue.js手机音乐app(一)基础组件scroll

时间:2023-04-03 00:36:02 HTML

1.基本实现(1)功能基本封装了better-scroll插件实现移动端的滚动(2)实现引入better-scrollpropsprobeType:better-scroll配置其中一项(1)Value:1时scrolling,会派发scroll事件,阻塞流。2.滚动时,实时派发scroll事件,不拦截。3除了实时派发滚动事件外,在滑动的情况下仍然可以实时派发滚动事件。(2)默认值:1click:点击事件是否生效refreshDelay:刷新事件的延迟时间listenScroll:是否监听滚动事件,如果监听滚动事件,父组件要绑定监听函数给自定义事件'onscroll'数据:使用用于控制滚动刷新并重新计算外部调用的高度数据enable()disable()refresh()scrollTo(x,y,time,[easing])的缓动值即可只能是swipe/swipeBounce/bouncescrollToElement(el,time,[offsetX],[offsetY],[easing])offsetX,offsetY为number或者true,true表示滚动到目标元素的中心,取值为设置滚动到目标元素的偏移量思路步骤在mountedhook中,在$nextTick()回调中初始化scroll实例。因为在初始化scroll实例的时候,必须保证其挂载对象(wrapper)的DOM已经渲染完毕。由于wrapper中的数据可能是异步获取的,所以必须放在$nextTick()中获取数据更新后的DOM,并进行height计算watch父组件传入的数据。dataDOM上的数据已更改。要获取更新后的DOM,在操作函数中,还必须在$nextTick()回调中刷新滚动条,刷新后会重新计算高度。这里setTimeout()与$nextTick()具有相同的效果。代码2.问题总结(1)与父组件的交互父组件中滚动下的内容必须被包裹起来,并且不能出现以下结构

...
...
父组件调用srcoll组件方法,dom操作...调用scroll中的方法:this.$refs.scrollName.methodName()操作dom(比如重写style):this.$refs.scrollName.$el.style当父组件引用到时的v-if和vscroll组件-show对它的影响,比如在player.vue组件中有如下结构。子组件scroll位于一个元素内,该元素具有v-show属性来控制显示。1、v-if和v-show的区别:v-if会适当的销毁和重建组件,只有在条件为真时才会渲染。v-show在整个父组件创建时渲染,只根据条件重写元素的css属性display的值来控制是否显示。2.当滚动在v-show控制的元素中时,必须手动调用scroll.refresh()刷新滚动,并在显示条件为真时重新计算其高度。3.当scroll在v-if控制的元素中时,不需要手动刷新,因为scroll组件会被重新创建,scroll内部mountedhook的初始化及其对数据的watch操作会自动更新高度准确实现滚动。4.在player.vue中,由于全屏播放器和迷你播放器会频繁切换,而且初始化开销不是很高,所以使用v-show控制显示,手动刷新滚动条watch的值player.isFullpage.能。//全屏播放器...//歌词,可滚动//组件挂载时后台获取lyricData...
//迷你显示播放器...
//js部分watchcodewatch:{'player.isFullpage':function(newFlag){if(newFlag){this.$nextTick(()=>{this.$refs.lyricScroll.refresh()})},...}-父组件和scroll组件同时触发touch系列事件的问题比如player.vue中,音乐播放器CD页和歌词页通过左右滑动显示,封装成一个fade-slider组件控制用于页面切换,监听fade-slider中的touch系列事件控制左右滑动,而歌词页面中使用scroll组件,监听onscroll事件控制歌词切换上和下。scroll和fade-slier是父子关系,所以直接绑定事件时,冒泡过程中会同时触发两者的touch系列事件。为了实现需求,即页面左右滑动时scroll禁止滚动,scroll上下滚动时fade-slider不左右切换,必须做相应的处理。以下代码://player.vue组件片段...
...//监听滚动滚动事件,这里主要是上下滚动...
//fade-slider组件的模板部分1.当要在歌词页面上下滑动歌词时,即在scroll上上下滚动时,让歌词页面(fade-slider组件中的页面之一)不左右滑动。这很简单。在fade-slider中判断触摸系列事件中触摸的位置和方向即可。2、反之,fade-slider控制歌词页左右滑动时,歌词页中的scroll不应该上下滑动,因为是封装的onscroll事件,无法直接判断滚动条的位置和方向触碰。虽然监听它的touch系列事件也能解决问题,但显然不适合,不仅逻辑重复,而且组件与DOM的耦合度太高,所以不适合。3、因此,目前的问题是在父组件的触摸过程中,当满足某些条件时,防止触发子组件的scroll事件。显然,在冒泡过程中很难做到,所以解决方法:(1)fade-slider捕获并绑定组件(父组件)中的触摸系列事件:如@touchstart.capture="onTouchStart"(2)触摸系列事件处理过程中,判断为左右滑动行为时进行控制,防止触摸系列事件的传播:e.stopPropagation(),这样就不会触发scroll中的滚动。4、因此,大体的逻辑是:(1)触摸系列事件被父组件第一时间捕获,判断触摸行为(2)如果是左右滑动,则切换页面,防止touch事件的进一步传递(3)如果是上下滑动,则不处理,从而触发并处理子组件(scroll内部)的touch系列事件。(2)自动滚动过程中触摸相关问题分析如下图所示:在歌词页面,歌词使用了滚动组件。在音乐播放过程中,会自动播放歌词,即根据当前音乐对应的歌词使用scrollToElement,并且在这个过程中,仍然接受触摸行为。当触摸引起滚动时,会暂停歌词自动播放,显示歌词控制条,并根据滚动距离高亮相应歌词。歌词控制栏分为两部分:左侧显示当前滚动歌词对应的音乐时间,右侧显示播放按钮,点击播放当前音乐,歌词会重新定位相应地图1:自动滚动时的歌词控件不显示条,高亮显示的歌词为当前音乐进度对应的歌词图2:触摸导致滚动时,歌词暂停(音乐播放状态不变),显示歌词控制条,当前高亮的歌词从当前滚动到定位问题分析首先,滚动过程中歌词控制条上显示的高亮歌词和对应时间明显判断为onscroll,那么问题就是在滚动过程中如何合理有效的区分自动播放和滚动。触摸引起的滚动。在确认触摸行为导致滚动的前提下,大致分为三个阶段,做不同的事情(1)scrollStart阶段:显示歌词控制条,停止歌词自动滚动(2)onScroll阶段:继续滚动根据当前滚动Shift更新高亮歌词,以及对应的时间(3)scrollEnd阶段:滚动结束后,设置一定时间(比如1s),隐藏歌词控制条,恢复之前的播放state(4)在以上阶段的任何时候,一旦点击歌词控制栏上的播放按钮,歌词控制栏将立即隐藏,并更新播放状态。总的来说,核心内容涉及到四个事件:touchStart、scrollStart、onScroll、scrollEnd。关键是这些事件的触发顺序,以及滚动惯性问题的解决(一)初步实现(一)ontouchStart、onscrollStart、onscroll、onscrollEnd事件已经绑定并注册到scroll组件中(代码见第一章)),并将相应的事件直接传入父组件(2)设置touchflag来区分是否是自动滚动。在touchStart中将其设置为true,在scrollEnd中将其设置为false。之所以用scrollEnd而不是touchEnd作为结束计时,也是因为滚动惯性(3)所以自动滚动和触摸滚动的处理流程如下:(2)惯性时触摸导致的bug修复过程流程基本就绪。实现需求,touchflag已经可以控制自动滚动和触摸滚动的区分,但是你会发现如果在scroll的惯性滚动过程中再次触摸屏幕,惯性滚动会停止,但是scroll系列事件将不再工作。高亮的歌词此时并没有对应到touch的位置,也就是touch标志在它的一系列事件中被设置为false,而这显然不是我们想要的。之所以将touchflag设置为false,是因为scrollEnd的触发。在惯性滚动过程中,触摸屏幕会阻止惯性滚动。这是一个明显的现象。据此想想,肯定是touch导致scrollEnd被提前触发了。即如下图所示:因此,除了触摸标志之外,还需要一个结束标志来判断滚动系列过程是否被触摸行为提前中断。1.在touchStart2中设置结束标志为true。在scrollStart3中将结束标志设置为false。在scrollEnd4中将结束标志设置为true。在scrollEnd中加入判断,如果结束标志为true,则不要将touch标志设置为false(3)滚动组件scrollStart、onscroll、scrollEnd中注册的touchStart、scrollStart、onscroll、scrollEnd的区别都是better-scroll注册的事件,用于better-scroll对象(newBetterScroll()).on(事件名,处理函数)监听touchStart是原生事件,绑定在scroll组件最外层元素上3.完整项目地址Github:https://github.com/aphasic/mu...