事件分析
事件区分核心:使用onMouseDown
、onMouseUp
和定时器来区分单击事件与长按事件
按下时设置长按事件定时器(并加入长按回调
),并记录当前时间戳,
松开事件中如果当前时间戳差值小于定时器则执行单击回调
,并清除定时器,如果大于定时器事件,则按下事件中定时器的长按回调
已经执行,事件末清除以上定时器
const mouseDown = (callBack) => {mouseTime.current = Date.now();clearInterval(timer.current);timer.current = null;setPlaying(false);funcTimer.current.timeOutTimer = setTimeout(() => {funcTimer.current.intervalTimer = setInterval(() => {callBack();}, 100);}, 480);};const mouseUp = (callBack) => {const funcType = Date.now() - mouseTime.current >= 500;if (funcType) {clearInterval(funcTimer.current.intervalTimer);} else {clearTimeout(funcTimer.current.timeOutTimer);callBack();}funcTimer.current = {};mouseTime.current = null;};
手搓播放器代码
import React, { useEffect, useRef, useState } from 'react';
import { Slider, Button } from 'antd';
import { PlayCircleOutlined, PauseCircleOutlined, BackwardOutlined, ForwardOutlined, XFilled } from '@ant-design/icons';const data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8,9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
];
function Index() {const [pointIndex, setPointIndex] = useState(0);const [playing, setPlaying] = useState(false);const timer = useRef(null);const mouseTime = useRef(null);const funcTimer = useRef({});function formatter(value) {return `${value}%`;}const play = () => {if (playing) {setPlaying(false);clearInterval(timer.current);timer.current = null;} else {setPlaying(true);timer.current = setInterval(() => {setPointIndex((c) => {if (c < data?.length - 1) {return c + 1;} else {setPlaying(false);clearInterval(timer.current);timer.current = null;return 0;}});}, 200);}};const mouseDown = (callBack) => {mouseTime.current = Date.now();clearInterval(timer.current);timer.current = null;setPlaying(false);funcTimer.current.timeOutTimer = setTimeout(() => {funcTimer.current.intervalTimer = setInterval(() => {callBack();}, 100);}, 480);};const mouseUp = (callBack) => {const funcType = Date.now() - mouseTime.current >= 500;if (funcType) {clearInterval(funcTimer.current.intervalTimer);} else {clearTimeout(funcTimer.current.timeOutTimer);callBack();}funcTimer.current = {};mouseTime.current = null;};const forwardFunc = () => {pointIndex !== data?.length && setPointIndex((c) => c + 1);};const backFunc = () => {pointIndex !== 0 && setPointIndex((c) => c - 1);};const reset = () => {setPointIndex(0);setPlaying(false);clearInterval(timer.current);timer.current = null;};return (<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh', width: '100%' }}><div style={{ width: '700px', display: 'flex' }}><Buttonicon={<BackwardOutlined />}onMouseDown={() => mouseDown(backFunc)}onMouseUp={() => mouseUp(backFunc)}/><Button icon={playing ? <PauseCircleOutlined /> : <PlayCircleOutlined />} onClick={play} /><Buttonicon={<ForwardOutlined />}onMouseDown={() => mouseDown(forwardFunc)}onMouseUp={() => mouseUp(forwardFunc)}/><Button icon={<XFilled style={{ fontSize: 12 }} />} onClick={reset} /><Slider// tipFormatter={formatter}style={{ width: '600px' }}value={pointIndex}max={data?.length - 1}onChange={(e) => {setPlaying(false);clearInterval(timer.current);timer.current = null;setPointIndex(e);}}/></div></div>);
}export default Index;