制作一个简单React移动端滑动切换组件

写在前边

  • 本文主要介绍如何实现滑动切换及遇到的问题,具体组件代码点这
  • 如果你需要的是轮播图,这里有两个轮子react-slicknuka-carousel
  • 原生DOM操作,非React框架下也能使用

实现效果
在这里插入图片描述

我们想实现触摸切换无非是做以下三件事

  1. 监听触摸事件
  2. 判断用户当前操作是否是切换
  3. 进行页面切换

获取触摸事件

如果你不了解触摸事件可以先看触摸事件
要想监听触摸事件整个流程需要监听以下三个事件

let lists = document.getElementsByClassName('tabs-ul-li');//我们监听的元素           
lists.addEventListener("touchstart", (e) => {
                    //e.targetTouches[0].pageX;
                    //e.targetTouches[0].pageY; 
});
lists.addEventListener("touchmove", (e) => {
					//e.targetTouches[0].pageX;
                    //e.targetTouches[0].pageY; 
});
lists.addEventListener("touchend", (e) => {
					//e.changedTouches[0].pageX;
					//e.changedTouches[0].pageY;
});

这里使用clientX/clientY、pageX/pageY都没有问题,我们需要的是偏移量,另外touchend事件触发时touches和targetTouches都被归0,使用changedTouches获取用户离开位置(单一触点的情况归0)

判断用户当前操作是否是切换

区分横向切换纵向滚动

一次触摸事件只执行一种操作,比如在屏幕上画7会触发切换不会触发滚动的。
这里我们想在用户横向滑动时切换页面,纵向滑动时滚动页面,需要在touchmove事件第一次触发时就判断用户到底是想滚动还是切换。当X轴偏移量大于Y轴偏移量时执行切换操作,小于等于时执行滚动。

             lists.addEventListener("touchmove", (e) => {
                    let disX = e.targetTouches[0].pageX - this.initPageX;
                    let disY = e.targetTouches[0].pageY - this.initPageY;
                    if (Math.abs(disX) - Math.abs(disY) > 0) {
                        this.touchEvent = 'switch';
                    } else {
                        this.touchEvent = 'scroll'
                    }
                });

滑动是touchmove的默认事件,所以在一次触摸操作被确定为切换时要取消touchmove的默认事件。

     lists.addEventListener("touchmove", (e) => {
                    e.preventDefault();
                }, {
                    passive: false//  禁止 passive 效果
                });

这里不写 passive: false在某些浏览器无法实现禁止默认事件,原因看这里

区分同向不同组件切换

使用targetTouches就是为了区别不同组件的同向切换事件,当然这是指组件没有共同区域的情况。如果不同切换事件有共同区域,我们也可以通过设置优先级来保证一次触摸操作只执行一个操作。

进行页面切换

切换时要考虑切换的方向

 lists.addEventListener("touchend", (e) => {
     let switchDirection = '';
     //在手指离开手机后touches和targetTouches中对应的元素会同时移除
     if (e.changedTouches[0].pageX - this.initPageX > 0) {
         switchDirection = 'left'
     } else if (e.changedTouches[0].pageX - this.initPageX < 0) {
         switchDirection = 'right'
     }
 });
React中实现移动端滑动加载可以使用一些第三方库来帮助我们完成。 其中比较常用的是react-infinite-scroll-component。该库实现了无限滚动的功能,当用户滚动到页面底部时会触发一个回调函数来加载更多数据,从而完成滑动加载的效果。 具体使用方法如下: 1. 安装库 ``` npm install react-infinite-scroll-component --save ``` 2. 引入库 ```javascript import InfiniteScroll from 'react-infinite-scroll-component'; ``` 3. 实现滑动加载的组件 ```javascript import React, { Component } from 'react'; import InfiniteScroll from 'react-infinite-scroll-component'; class ScrollLoad extends Component { state = { items: [], hasMore: true, page: 1, }; componentDidMount() { this.fetchData(); } fetchData = () => { const { page } = this.state; fetch(`https://jsonplaceholder.typicode.com/photos?_page=${page}&_limit=10`) .then((response) => response.json()) .then((data) => { this.setState({ items: [...this.state.items, ...data], page: page + 1, hasMore: data.length === 10, }); }); }; render() { const { items, hasMore } = this.state; return ( <InfiniteScroll dataLength={items.length} next={this.fetchData} hasMore={hasMore} loader={<h4>Loading...</h4>} > {items.map((item) => ( <div key={item.id}> <h3>{item.title}</h3> <img src={item.url} alt={item.title} /> </div> ))} </InfiniteScroll> ); } } export default ScrollLoad; ``` 在上面的代码中,我们使用了一个列表来展示数据,同时使用了react-infinite-scroll-component来实现滑动加载的效果。在组件中,我们使用state来保存数据和一些状态,通过fetchData方法来加载更多数据,当用户滑动到页面底部时,会自动触发next方法来加载更多数据。同时,我们还设置了一个loader来显示正在加载中的提示。 最后,我们将列表包裹在InfiniteScroll组件中,设置hasMore属性为true,表示还有更多的数据需要加载,dataLength属性表示当前已经加载的数据的长度,next属性表示下一次需要加载数据的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值