功能介绍:

在PC端网页,包括大数据、官网、后台管理平台开发中,可能会用到这种列表循环滚动的展示。

大致需求:

  1. 列表可以使用数组循环遍历;
  2. 每隔几秒中列表数据向上滚动一定距离,展示下一条数据;
  3. 滚动到最后一条数据时重新显示第一条开始的数据(类似走马灯、banner图的循环效果);

整体思路:

  1. 使用两个定时器嵌套实现;
  2. 需要两个相同容器存放同样内容,实现无缝衔接效果;

效果展示:

请添加图片描述

完整代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script>
		<style>
			/* 滚动表格最外层 */
			.tableoOut {
				margin: 100px auto;
			    width: 500px;
			    height: 400px;
				background: pink;
			    overflow: hidden;
			    display: flex;
			    align-items: center;
			    justify-content: center;
			    flex-direction: column;
			}
			.tableBox {
			    width: 100%;
				background: #000;
			    overflow: hidden
			}
			.tableTit {
				background: #000;
			    width: 100%;
			    height: 40px;
			    color: #858A84;
			    text-align: center;
			    display: flex;
			    justify-content: center;
			    align-items: center;
			}
			.tableInner {
			    height: auto;
			}
			.box {
			    width: 100%;
			    height: 50px;
			    display: flex;
			    justify-content: center;
			    align-items: center;
			    color: #fff;
			}
			.box .time {
			    color: #858A84;
			}
			.tableoOut .addr, .tableoOut .time, .tableoOut .name {
			    box-sizing: border-box;
			    padding: 0 5px;text-align: center;
			    overflow: hidden;
				white-space: nowrap;
				text-overflow: ellipsis;
			}
			.tableoOut .addr {
			    width: calc(100% - 200px);
			    flex-shrink: 0;
			}
			.tableoOut .name, .tableoOut .time {
			    width: 100px;
			    flex-shrink: 0;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<div class="tableoOut" ref="tableoOut">
				<div class="tableTit">
					<div class="name">姓名</div>
					<div class="addr">地址</div>
					<div class="time">入驻时间</div>
				</div>
				<div class="tableBox" ref="tableBox"
					:style="{height: tableHei}">
					<div class="tableInner" ref="tableInner">
						<div class="box" v-for="item in 7" :key="item">
							<div class="name">{{item}}</div>
							<div class="addr">山东省山东省山东省山东省山东省山东省山东省山东省
							山东省山东省山东省山东省山东省</div>
							<div class="time">2022-05-26</div>
						</div>
					</div>
					<div class="tableInner" v-if="size < 7">
						<div class="box" v-for="item in 7" :key="item">
							<div class="name">{{item}}</div>
							<div class="addr">山东省山东省山东省山东省山东省山东省山东省山东省
							山东省山东省山东省山东省山东省</div>
							<div class="time">2022-05-26</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</body>
	<script>
		new Vue({
			el: '#app',
			data: {
				tableHei: 'auto',
				timer: null,
				size: 0
			},
			mounted() {
				this.getTable();
			},
			methods: {
				getTable() {
					const outHei = this.$refs.tableoOut.clientHeight - 60;
					this.size = Math.floor(outHei / 50);
					this.tableHei = this.size * 50 + 'px';
					this.scrolls();
				},
				stepScroll() {
					const step = 50;
					let num = 0;
					const tableBox = this.$refs.tableBox;
					const stepTime = setInterval(function () {
						num += 2;
						if (num > step) {
							num = 0;
							clearInterval(stepTime);
						} else {
							tableBox.scrollTop += 2;
						}
					}, 20);
				},
				scrolls() {
					const that = this;
					const tableBox = this.$refs.tableBox;
					const tableInner = this.$refs.tableInner;
					clearInterval(this.timer);
					this.timer = setInterval(function () {
						if(tableBox.scrollTop === tableInner.scrollHeight) {
							tableBox.scrollTop = 0;
						}
						that.stepScroll();
					}, 2000);
				},
			}
		})
	</script>
</html>

setInterval踩坑:

发现这种方法实现的定时轮播,有一阵没访问页面,会出现卡停的情况,采用下面的解决方法:

<script>
	new Vue({
		el: '#app',
		data: {
			tableHei: 'auto',
			timer: null,
			size: 0,
			stopSign: true, // 判断定时器是否停止标识
			stepTime: null, // 改为全局定时器
		},
		mounted() {
			const that = this;
			// 增加浏览器激活状态判断。非激活状态为onblur
			window.onfocus = function(e) {
				const tableBox = that.$refs.tableBox;
				const sT = tableBox.scrollTop;
				console.log("激活状态!")
				if (!that.stopSign) {
					tableBox.scrollTop = Math.round(sT / 50) * 50;
					clearInterval(that.stepTime);
				}
			}
			this.getTable();
		},
		methods: {
			getTable() {
				const outHei = this.$refs.tableoOut.clientHeight - 60;
				this.size = Math.floor(outHei / 50);
				this.tableHei = this.size * 50 + 'px';
				this.scrolls();
			},
			stepScroll() {
				const that = this;
				const step = 50;
				let num = 0;
				const tableBox = this.$refs.tableBox;
				// 改为全局定时器,且在调用前先进行清空
				clearInterval(this.stepTime);
				this.stepTime = setInterval(function () {
					that.stopSign = false;
					num += 2;
					if (num > step) {
						num = 0;
						clearInterval(that.stepTime);
						that.stopSign = true;
					} else {
						tableBox.scrollTop += 2;
					}
				}, 1000 / 60);
			},
			scrolls() {
				const that = this;
				const tableBox = this.$refs.tableBox;
				const tableInner = this.$refs.tableInner;
				clearInterval(this.timer);
				this.timer = setInterval(function () {
					// 修改定时器结束判断条件
					if(tableBox.scrollTop >= tableInner.scrollHeight) {
						tableBox.scrollTop = 0;
					}
					that.stepScroll();
				}, 2000);
			},
		}
	})
</script>
Logo

前往低代码交流专区

更多推荐