前言
最近在公司开发项目的时候,原生滚动条中有些东西没办法自定义去精细的控制,于是开发一个类似于better-scroll一样的浏览器滚动监听的JS实现,下面我们就来探究一下自定义滚动需要考虑哪些东西,经过哪些过程。话不多说了,来一起看看详细的介绍吧。
选择滚动监听的事件
因为是自定义手机端的滚动事件,那我选择的是监听手机端的三个touch事件来实现监听,并实现了两种滚动效果,一种是通过-webkit-transform,一种是通过top属性。两种实现对于滚动的基本效果够能达到,可是top的不适合滚动中还存在滚动,可是能解决滚动中存在postion:fixed
属性的问题;而transform可以实现滚动中有滚动,可是又不能解决postion:fixed
的问题,所以,最后选择性考虑使用哪一种实现方式,用法一样。
主要的实现业务逻辑
handleTouchMove(event){ event.preventDefault(); this.currentY = event.targetTouches[0].screenY; this.currentTime = new Date().getTime(); // 二次及以上次数滚动(间歇性滚动)时间和路程重置计算,0.05是间歇性滚动的停顿位移和时间比 if (Math.abs(this.currentY - this.lastY) / Math.abs(this.currentTime - this.lastTime) < 0.05) { this.startTime = new Date().getTime(); this.resetY = this.currentY; } this.distance = this.currentY - this.startY; let temDis = this.distance + this.oldY; /*设置移动最小值*/ temDis = temDis > this.minValue "top"] = temDis + 'px'; this.lastY = this.currentY; this.lastTime = this.currentTime; this.dispatchEvent(); this.scrollFunc(event); },
代码解读:这是监听touchmove事件的回调,其中主要计算出目标节点this.$el
的top或者-webkit-transform中translateY的值,而计算的参考主要以事件节点的screenY的垂直移动距离为参考,当然其中还要判断一下最大值和最小值,为了保证移动可以的超出最大值小值一定的距离所以加了一个1/3的移动计算。这里可能主要到了有一个间歇性滚动的判断和计算,主要是服务于惯性滚动的,目的是让惯性滚动的值更加精确。
handleTouchEnd(event){ /*点透事件允许通过*/ if (!this.distance) return; event.preventDefault(); let temDis = this.distance + this.oldY; /*计算缓动值*/ temDis = this.computeSlowMotion(temDis); /*设置最小值*/ temDis = temDis > this.minValue "transitionDuration"] = '500ms'; this.$el.style["transitionTimingFunction"] = 'ease-out'; /*确定最终的滚动位置*/ setTimeout(()=> { this.$el.style["top"] = temDis + 'px'; }, 0); // 判断使用哪一种监听事件 if (this.slowMotionFlag) { this.dispatchEventLoop(); } else { this.dispatchEvent(); } this.$el.addEventListener('transitionend', ()=> { window.cancelAnimationFrame(this.timer); }); this.scrollFunc(event); }
代码解读:这是touchend事件监听的回调,其中这里要判断是否要拦截click和tap事件,并且这里还要计算惯性缓动值,设置最终的最大最小值,以及设置动画效果和缓动效果。下面来谈一下滚性滚动的计算:
// 计算惯性滚动值 computeSlowMotion(temDis){ var duration = new Date().getTime() - this.startTime; // 300毫秒是判断间隔的最佳时间 var resetDistance = this.currentY - this.resetY; if (duration < 300 && Math.abs(resetDistance) > 10) { var speed = Math.abs(resetDistance) / duration, destination; // 末速度为0 距离等于初速度的平方除以2倍加速度 destination = (speed * speed) / (2 * this.deceleration) * (resetDistance < 0 "color: #ff0000">代码解读:滚性滚动的算法主要是根据一个路程和时间计算出初速度,以及原生滚动的加速度的大于值0.006来计算滚动的总位移。这里主要还要判断一下一个300ms的经验值。总结
大概的流程和思考就是这样了,后续还会增加更多的功能进行扩展
附上git地址:https://github.com/yejiaming/scroll
本地下载:http://xiazai.jb51.net/201710/yuanma/js-scroll-custom(jb51.net).rar
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 中国武警男声合唱团《辉煌之声1天路》[DTS-WAV分轨]
- 紫薇《旧曲新韵》[320K/MP3][175.29MB]
- 紫薇《旧曲新韵》[FLAC/分轨][550.18MB]
- 周深《反深代词》[先听版][320K/MP3][72.71MB]
- 李佳薇.2024-会发光的【黑籁音乐】【FLAC分轨】
- 后弦.2012-很有爱【天浩盛世】【WAV+CUE】
- 林俊吉.2012-将你惜命命【美华】【WAV+CUE】
- 晓雅《分享》DTS-WAV
- 黑鸭子2008-飞歌[首版][WAV+CUE]
- 黄乙玲1989-水泼落地难收回[日本天龙版][WAV+CUE]
- 周深《反深代词》[先听版][FLAC/分轨][310.97MB]
- 姜育恒1984《什么时候·串起又散落》台湾复刻版[WAV+CUE][1G]
- 那英《如今》引进版[WAV+CUE][1G]
- 蔡幸娟.1991-真的让我爱你吗【飞碟】【WAV+CUE】
- 群星.2024-好团圆电视剧原声带【TME】【FLAC分轨】