0


vue组件:列表自动无限循环

前述:用过vue-seamless-scroll插件,手动滚动列表到底部出现了空白现象,某些表现不符合项目场景,故自己写了一个自己用的组件,如果有人需要可以直接拿去用,如有不足请指教勿喷!

主要功能:

  1. 列表自动无限循环滚动
  2. 鼠标移入停止滚动,移出继续滚动
  3. 待滚动内容高度未铺满并超过容器高度时不滚动
  4. 支持滚动速度、单次滚动时间间隔、单次滚动高度,三个参数控制
  5. 可自己手动滚动列表

效果图 :

组件代码:

  1. <template>
  2. <div class="scroll-outer" ref="outer" @mouseover="onMouseover" @mouseleave="onMouseleave">
  3. <div class="scroll-inner-box" ref="scrollBox">
  4. <div class="scroll-item-box" ref="scrollItemBox">
  5. <slot></slot>
  6. </div>
  7. <div v-if="showSecond" class="scroll-item-box">
  8. <slot></slot>
  9. </div>
  10. </div>
  11. </div>
  12. </template>
  13. <script>
  14. export default {
  15. name: "my-auto-scroll",
  16. props: {
  17. list: {
  18. type: Array,
  19. default: () => [
  20. { name: "张三1" },
  21. { name: "张三2" },
  22. { name: "张三3" },
  23. { name: "张三4" },
  24. { name: "张三5" },
  25. { name: "张三6" },
  26. { name: "张三7" },
  27. { name: "张三8" },
  28. { name: "张三9" },
  29. { name: "张三10" },
  30. ],
  31. },
  32. speed: {
  33. type: Number,
  34. default: 0.1,
  35. },
  36. //滚动作单步运动时的单纯运动距离
  37. singleHeight: {
  38. type: Number,
  39. default: 0,
  40. },
  41. //单步运动的时间间隔
  42. waitTime: {
  43. type: Number,
  44. default: 0,
  45. },
  46. },
  47. data() {
  48. return {
  49. rafId: null,
  50. y: 0,
  51. showSecond: false,
  52. controleHeight: 0,
  53. };
  54. },
  55. watch: {
  56. list: {
  57. handler(newVal) {
  58. var that = this;
  59. this.$nextTick(() => {
  60. console.log(newVal);
  61. if (newVal && newVal.length > 0) {
  62. let scrollBox = that.$refs.scrollBox;
  63. let outer = that.$refs.outer;
  64. if (this.myReq) {
  65. cancelAnimationFrame(this.myReq);
  66. }
  67. // 开启动画
  68. if (this.canRun()) this.reqAnimationFrame();
  69. // this.reqAnimationFrame();
  70. // 手动滚动到底部时滚动条重置到最上边,同时滚动盒子重置为top:0
  71. outer.addEventListener("scroll", function () {
  72. if (
  73. outer.scrollTop + outer.clientHeight + 4 >=
  74. outer.scrollHeight
  75. ) {
  76. outer.scrollTop = 0;
  77. that.y = 0;
  78. scrollBox.style.top = 0;
  79. }
  80. });
  81. }
  82. });
  83. },
  84. deep: true,
  85. immediate: true,
  86. },
  87. },
  88. mounted() {
  89. window.addEventListener("resize", this.listenResizeFn);
  90. },
  91. methods: {
  92. listenResizeFn() {
  93. cancelAnimationFrame(this.myReq);
  94. if (this.canRun()) this.reqAnimationFrame();
  95. },
  96. onMouseover() {
  97. clearTimeout(this.timer);
  98. cancelAnimationFrame(this.myReq);
  99. },
  100. onMouseleave() {
  101. if (this.canRun()) this.reqAnimationFrame();
  102. },
  103. canRun() {
  104. let scrollItemBox = this.$refs.scrollItemBox;
  105. let scrollBox = this.$refs.scrollBox;
  106. let outer = this.$refs.outer;
  107. // 开启动画条件:滚动盒子(scrollBox)高度高于外层容器(outer)高度
  108. if (outer.offsetHeight >= scrollItemBox.offsetHeight) {
  109. this.showSecond = false;
  110. outer.scrollTop = 0;
  111. this.y = 0;
  112. scrollBox.style.top = 0;
  113. return false;
  114. } else {
  115. this.showSecond = true;
  116. return true;
  117. }
  118. },
  119. //获取dom元素的高度:content+padding+margin+border
  120. getComputedHeight(dom) {
  121. let computedStyle = getComputedStyle(dom);
  122. let computedHeight =
  123. dom.offsetHeight +
  124. parseFloat(computedStyle.marginTop) +
  125. parseFloat(computedStyle.marginBottom);
  126. return computedHeight;
  127. },
  128. reqAnimationFrame() {
  129. //外层容器
  130. let outer = this.$refs.outer;
  131. //滚动盒子
  132. let scrollBox = this.$refs.scrollBox;
  133. //滚动盒子下边的第一个scroll-item-box,
  134. let scrollItemBox = this.$refs.scrollItemBox;
  135. //滚动速度
  136. this.speed = this.speed > 1 ? 1 : this.speed < 0 ? 0.1 : this.speed;
  137. //取第一个scrollItemBox高度
  138. let definedHeight = this.getComputedHeight(scrollItemBox);
  139. //持续滚动
  140. this.y = this.y + this.speed;
  141. scrollBox.style.top = -this.y + "px";
  142. //====添加滚动间隔控制====开始
  143. if (this.singleHeight >= 20 && this.waitTime > 500) {
  144. if (this.controleHeight >= this.singleHeight) {
  145. cancelAnimationFrame(this.myReq);
  146. this.controleHeight = 0;
  147. this.timer = setTimeout(() => {
  148. if (this.canRun) this.reqAnimationFrame();
  149. }, this.waitTime);
  150. return;
  151. } else {
  152. // 一次移动高度未达到指定距离继续执行动画
  153. this.controleHeight += this.speed;
  154. }
  155. }
  156. //====添加滚动间隔控制====结束
  157. //当滚动到第一个scroll-item-box高度时scrollBox重置为top:0,视觉上是无缝滚动
  158. if (this.y >= definedHeight) {
  159. this.y = 0;
  160. }
  161. this.myReq = window.requestAnimationFrame(this.reqAnimationFrame);
  162. },
  163. },
  164. destroyed() {
  165. window.removeEventListener("resize", this.listenResizeFn);
  166. cancelAnimationFrame(this.myReq);
  167. if (this.timer) clearTimeout(this.timer);
  168. },
  169. };
  170. </script>
  171. <style lang="scss">
  172. .scroll-outer {
  173. height: 100%;
  174. overflow-x: hidden;
  175. position: relative;
  176. &::-webkit-scrollbar {
  177. width: 0.3vw;
  178. }
  179. &:hover::-webkit-scrollbar-track {
  180. -webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
  181. border-radius: 0.1vw;
  182. background-color: #295099;
  183. opacity: 1;
  184. // display: none;
  185. }
  186. &:hover::-webkit-scrollbar-thumb {
  187. opacity: 1;
  188. border-radius: 0.1vw;
  189. -webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
  190. background-color: #0ba9ea;
  191. }
  192. }
  193. .scroll-inner-box {
  194. height: auto;
  195. position: absolute;
  196. width: 100%;
  197. top: 0;
  198. left: 0;
  199. }
  200. </style>

使用示例:

  1. import autoScroll from "@/components/autoScroll";
  1. <autoScroll :list="list" :speed="0.5" :waitTime="2000" :singleHeight="100">
  2. <div class="t-item" v-for="(item,index) in list" :key="index">
  3. <div class="tvalue" style="flex: 0 0 30%;">{{ item.jgjc }}</div>
  4. <span class="tvalue">{{ item.total||'--' }}</span>
  5. <span class="tvalue" style="color:#0FCBDE">{{ item.ypc||'--' }}</span>
  6. <span class="tvalue" style="color:#F15730">{{ item.zlz||'--' }}</span>
  7. <span class="tvalue" style="color:#17DB68">{{ item.zlwc||'--' }}</span>
  8. </div>
  9. </autoScroll>

使用注意:

  1. autoScroll容器默认是占外层容器宽高百分百,要自己在autoScroll外层加个容器
  2. 参数waitTIme和singleHeight同时存在,才能出现滚动动画间隔执行的效果
  3. 样式用了sass,如果有问题可以去掉或者导入sass

本文转载自: https://blog.csdn.net/qq_36764510/article/details/129821226
版权归原作者 The ever Boy 所有, 如有侵权,请联系我们删除。

“vue组件:列表自动无限循环”的评论:

还没有评论