uniapp不用scroll-view做一個左右切換滾動,自動判定切換到下一個內容塊,如果鼠標移動距離過短不讓切換走,讓退回去,內容旋轉360度並切換裏面內容的效果

先看效果:
在這裏插入圖片描述
直接上代碼好了,JS註釋特別詳細:

<template>
	<view class="test" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">
		<view class="box" :class="{istrans:transFlag}" :style="'width:'+screenWidth*list.length+'px;height:'+screenHeight+'px;left:'+scrollLeft+'px'">
			<view class="in-box" :style="'width:'+screenWidth+'px;height:'+screenHeight+'px;'" @click.stop="clickNow(index)"
			 v-for="(item,index) of list" :key="index">
				<view class="content" :class="{rotate:item.clickFlag}" :style="'background:'+(item.clickFlag?'#F00;':'#E5E5E5;')">
					{{item.contentFlag?item.content1:item.content2}}
				</view>
			</view>
		</view>
	</view>
</template>

	export default {
		data() {
			return {
				list: [ //模擬數據
					{
						id: 1,
						content1: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis aliquam quo fugiat iusto eum debitis laudantium odit maxime sint magni illum assumenda doloremque velit explicabo modi consectetur cupiditate non fuga.',
						content2: '改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容'
					},
					{
						id: 2,
						content1: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis aliquam quo fugiat iusto eum debitis laudantium odit maxime sint magni illum assumenda doloremque velit explicabo modi consectetur cupiditate non fuga.',
						content2: '改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容'
					},
					{
						id: 3,
						content1: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis aliquam quo fugiat iusto eum debitis laudantium odit maxime sint magni illum assumenda doloremque velit explicabo modi consectetur cupiditate non fuga.',
						content2: '改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容'
					},
					{
						id: 4,
						content1: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis aliquam quo fugiat iusto eum debitis laudantium odit maxime sint magni illum assumenda doloremque velit explicabo modi consectetur cupiditate non fuga.',
						content2: '改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容'
					},
					{
						id: 5,
						content1: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis aliquam quo fugiat iusto eum debitis laudantium odit maxime sint magni illum assumenda doloremque velit explicabo modi consectetur cupiditate non fuga.',
						content2: '改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容'
					},
					{
						id: 6,
						content1: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis aliquam quo fugiat iusto eum debitis laudantium odit maxime sint magni illum assumenda doloremque velit explicabo modi consectetur cupiditate non fuga.',
						content2: '改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容'
					},
					{
						id: 7,
						content1: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis aliquam quo fugiat iusto eum debitis laudantium odit maxime sint magni illum assumenda doloremque velit explicabo modi consectetur cupiditate non fuga.',
						content2: '改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容'
					},
					{
						id: 8,
						content1: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis aliquam quo fugiat iusto eum debitis laudantium odit maxime sint magni illum assumenda doloremque velit explicabo modi consectetur cupiditate non fuga.',
						content2: '改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容'
					},
					{
						id: 9,
						content1: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis aliquam quo fugiat iusto eum debitis laudantium odit maxime sint magni illum assumenda doloremque velit explicabo modi consectetur cupiditate non fuga.',
						content2: '改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容'
					},
					{
						id: 10,
						content1: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis aliquam quo fugiat iusto eum debitis laudantium odit maxime sint magni illum assumenda doloremque velit explicabo modi consectetur cupiditate non fuga.',
						content2: '改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容改變一個內容'
					}
				],
				screenWidth: 0, //屏幕寬
				screenHeight: 0, //屏幕高

				transFlag: true, //是否有過渡,控制鼠標離開之後的動作

				startX: 0, //記錄點擊鼠標位置初始值
				startLeft: 0, //記錄點擊的時候當前 scrollLeft

				scrollLeft: 0, //模擬滾動的 left
				curIndex: 0, //當前滾動的位置對應的數據下標

				sensitivity: 120, //感應靈敏度,爲反比 值越大,靈敏度越低
			}
		},
		onLoad: function() {
			this.initData();
		},
		methods: {
			//數據初始化
			initData: function() {
				this.getScreenParams();
				this.getData();
			},
			//獲取屏幕參數
			getScreenParams: function() {
				uni.getSystemInfo({ //獲取系統參數
					success: (res) => {
						this.screenWidth = res.windowWidth;
						this.screenHeight = res.windowHeight;
					}
				});
			},
			//獲取數據並處理數據
			getData: function() {
				let list = JSON.parse(JSON.stringify(this.list));
				list.map(el => {
					el.clickFlag = false; //初始值,控制背景和旋轉
					el.contentFlag = false; //初始值,控制裏面內容
				})
				this.list = list;
			},
			//點擊當前content
			clickNow: function(index) {
				this.list[index].clickFlag = !this.list[index].clickFlag; //開始旋轉

				setTimeout(() => {
					this.list[index].contentFlag = !this.list[index].contentFlag; //內容在 3/4 秒後變化
				}, 750) //之所以是750ms 因爲旋轉動畫是 1s 3/4 秒的時候剛好旋轉到了 270deg,模擬用戶看不到的情況下改變內容
			},
			//觸摸屏幕 開始
			touchStart: function(e) {
				let touche = e.changedTouches[0];
				this.transFlag = false;
				this.startX = touche.clientX; //記錄當前鼠標位置
				this.startLeft = this.scrollLeft; //記錄當前內容的滾動位置
			},
			//觸摸移動
			touchMove: function(e) {
				let touche = e.changedTouches[0];
				let mX = touche.clientX;
				let diff = mX - this.startX; //鼠標移動距離

				this.scrollLeft = this.startLeft + diff; //鼠標沒離開的時候鼠標移動讓內容跟着鼠標走
			},
			//觸摸屏幕 結束
			touchEnd: function(e) {
				this.transFlag = true;
				let touche = e.changedTouches[0];
				let eX = touche.clientX; //結束時鼠標所在位置
				let diff = eX - this.startX; //鼠標移動距離
				if (Math.abs(diff) > this.sensitivity) { //手指移動距離大於靈敏度,意味着切換當前內容
					//不用考慮等於0的情況,等於0直接在靈敏度那兒就卡住過不來了
					let index = this.curIndex;
					let absLeft = Math.abs(this.scrollLeft); //取絕對值,用來判斷當前下標用的
					if (diff > 0) { //大於0 說明鼠標往右滑動,即將展示左側內容,下標應該往小了取,所以下方用的向下取整
						index = Math.floor(absLeft / this.screenWidth)
					} else { //小於0  說明鼠標往左滑動,即將展示右側內容,下標應該往大了取,所以下方用的向上取整
						index = Math.ceil(absLeft / this.screenWidth)
					}
					if (index > this.list.length - 1) { //控制一下,下標不能大於 list 的最大下標,至於小於0 這個情況不會出現
						index = this.list.length - 1
					}
					this.scrollLeft = -this.screenWidth * index;
					this.curIndex = index; //記錄一下當前顯示的下標是哪個
				} else { //手指移動距離不夠,這兒就體現了靈敏度的作用了,回去
					this.scrollLeft = this.startLeft;
				}
			},
		}
	}
	

	.test {
		overflow: visible;

		.box {
			font-size: 0;
			position: relative;
			left: 0; //模擬滾動
			.in-box {
				display: inline-block;
				text-align: center;
				.content {
					display: inline-block;
					vertical-align: middle;
					width: 80%;
					height: 90%;
					margin: 0 auto;
					font-size: 18px;
					background: #e5e5e5;
					border: 1px solid #999999;
					border-radius: 6px;
					transition: all 1s linear;
					transform: rotateY(0deg);
				}

				.content.rotate {
					transform: rotateY(360deg);
				}

				&::after {
					content: '';
					display: inline-block;
					vertical-align: middle;
					height: 100%;
					width: 0;
				}
			}

			&.istrans {
				transition: left 0.3s ease-in-out; //模擬滾動的動畫,實際上是過渡屬性
			}
		}
	}
	

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章