背景
当头部是轮播图,下边是下拉刷新列表时,在 @1 下拉刷新没有问题,在@2斜线下拉,会触发轮播图和下拉刷新
解决思路
当手指按下的时候监听按下所在的位置,如果是在下拉刷新容器内,不做任务操作,如果是不在下拉刷新容器内,禁用下拉刷新
第一步:封装带有禁用antd的list-view
import { ListView as AntListView, PullToRefresh } from 'antd-mobile';
import { ListViewProps } from 'antd-mobile/lib/list-view';
import classnames from 'classnames';
import React, { useImperativeHandle, useRef } from 'react';
import { Indicator } from 'rmc-pull-to-refresh/lib/PropsType';
import styles from './index.less';
interface Props extends ListViewProps {
height?: string | number;
refreshing?: boolean;
onRefresh: () => void;
indicator?: Indicator;
ref?: any;
/**
*是否禁用下拉刷新
* @default false 默认开启下拉刷新
*/
disablePullToRefresh?: boolean;
}
export interface ListRefProps {
getListRef: () => any;
}
/**
* 禁用下拉刷新容器className
*/
export const disableClassName = 'disable-pull-to-refresh';
const ListView = React.forwardRef<ListRefProps, Props>(
({ className, height, disablePullToRefresh, refreshing, onRefresh, indicator, ...otherProps }, listRef) => {
const pullIndicator = indicator;
const ref = useRef();
useImperativeHandle(listRef, () => ({
getListRef() {
return ref.current;
},
}));
return (
<AntListView
style={{
height,
overflow: 'auto',
}}
pageSize={4}
ref={ref}
scrollRenderAheadDistance={500}
onEndReachedThreshold={10}
className={classnames(styles.listView, className)}
pullToRefresh={
disablePullToRefresh ? (
<div className={disableClassName} />
) : (
<PullToRefresh
distanceToRefresh={undefined}
direction={undefined}
getScrollContainer={undefined}
refreshing={refreshing}
onRefresh={onRefresh}
indicator={pullIndicator}
/>
)
}
{...otherProps}
/>
);
}
);
export default React.memo(ListView);
第二步:在包含轮播图和下拉刷新的容器中写一个hook
import { useEffect, useRef, useState } from 'react';
import { parentsUntil } from './util';
/**
* 判断是否需要禁止下拉刷新,true 禁用下拉刷新,false 启用下拉刷新
*/
const useDisablePullRefresh = () => {
const [disablePullRefresh, setDisablePullRefresh] = useState(false);
const ref = useRef(false);
ref.current = disablePullRefresh;
useEffect(() => {
const touchstart = (e: TouchEvent) => {
const el = e.target as HTMLElement;
if (el) {
const arr = parentsUntil(el, 'body', '.am-list-body');
if (arr.length) {
if (ref.current !== false) {
setDisablePullRefresh(false);
}
} else if (ref.current !== true) {
setDisablePullRefresh(true);
}
}
};
const touchend = () => {
if (ref.current !== false) {
setDisablePullRefresh(false);
}
};
document.addEventListener('touchstart', touchstart);
document.addEventListener('touchend', touchend);
return () => {
document.removeEventListener('touchstart', touchstart);
document.removeEventListener('touchend', touchend);
};
}, []);
return disablePullRefresh;
};
export default useDisablePullRefresh;
在使用的下拉刷新业务组件中引入此hook添加disabled就可以了
这样就完美的解决了轮播图和下拉刷新冲突的问题了