uni-app scroll-view 点击实现元素居中

22 阅读2分钟

效果一:当前点击子元素靠左展示

01.gif

效果二:当前点击子元素靠左留一展示

02.gif

效果三:当前点击子元素居中展示

03.gif

<template>
	<view class="lxy-content">
		<scroll-view class="scroll-view" scroll-x scroll-with-animation :scroll-left="scrollLeft">
			<view class="scroll-item" :class="{ 'active': activeIndex == index }" v-for="(item,index) in category" :key="index"
				:id="'top'+index" @click="activeHandler(item, index)">
				<text>{{item.dw}}</text>
			</view>
		</scroll-view>
	</view>
</template>
<script>
export default {
  data() {
    return {
		contentScrollW: 0,
		scrollLeft: 0,
		activeIndex: 0,
		topintoindex: 'top0',
		category: [
		  { dw: "大庆" },
		  { dw: "吉林" },
		  { dw: "辽河" },
		  { dw: "华北" },
		  { dw: "大港" },
		  { dw: "冀东" },
		  { dw: "新疆" },
		  { dw: "塔里木" },
		  { dw: "吐哈" },
		  { dw: "长庆" },
		  { dw: "青海" },
		  { dw: "玉门" },
		  { dw: "西南" },
		  { dw: "浙江" },
		  { dw: "南方" },
		  { dw: "煤层气" }
		],
    };
  },
  mounted() {
	  this.getScrollW();
  },
  methods: {
	// 获取宽度和每个子元素节点的宽度以及元素距离左边栏的距离
	getScrollW() {
		const query = uni.createSelectorQuery().in(this);
		query.select('.scroll-view').boundingClientRect(data => {
			// 获取scroll-view组件宽度
			this.contentScrollW = data.width;
		}).exec();
		
		query.selectAll('.scroll-item').boundingClientRect(data => {
			let dataLen = data.length;
			for(let i = 0; i < dataLen; i++) {
				// scroll-view 子元素组件距离左边栏距离
				this.category[i].left = data[i].left;
				// scroll-view 子元素组件宽度
				this.category[i].width = data[i].width;
			}
		}).exec();
	},
	// 选择
	activeHandler(row, index) {
		this.activeIndex = index;
		this.topintoindex = 'top' + index;
		// 效果一(当前点击子元素靠左展示) 局限性:子元素宽度相同
		this.scrollLeft = index * this.category[index].width;
		// 效果一(当前点击子元素靠左展示) 子元素宽度不相同也可实现
		/* this.scrollLeft = 0;
		for(let i = 0; i < index; i++) {
			this.scrollLeft += this.category[i].width;
		}; */
		
		// 效果二(当前点击子元素靠作留一展示) 局限性:子元素宽度相同
		/* this.scrollLeft = (index - 1) * this.category[index].width */
		// 效果二(当前点击子元素靠左留一展示) 推荐:子元素宽度不相同也可实现
		/* this.scrollLeft = 0;
		for(let i = 0; i < index - 1; i++) {
			this.scrollLeft += this.category[i].width;
		}; */
		
		// 效果三(当前点击子元素居中展示) 不受子元素宽度影响
		/* this.scrollLeft = this.category[index].left - this.contentScrollW / 2 + this.category[index].width / 2; */
	}
  },
  destroyed() {
	console.log('卸载');
  }
}
</script>
<style lang="scss" scoped>
.lxy-content {
	
}
.scroll-view{
	width: 100%;
	white-space: nowrap;
	.scroll-item {
		display: inline-block;
		font-size: 32rpx;
		padding: 10rpx 30rpx;
		margin: 15rpx 0;
		margin-right: 20rpx;
		background-color: #f1f1f1;
		border-radius: 25rpx;
	}
	.active {
		background-color: #3a87ff;
		color: #fff;
	}
}

// 不显示滚动条
/deep/ ::-webkit-scrollbar {
	display: none;
	width: 0px !important;
	height: 0px !important;
}
</style>