单击事件<->长按时间:手搓播放器
事件分析
事件区分核心:使用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' }}>
<Button
icon={<BackwardOutlined />}
onMouseDown={() => mouseDown(backFunc)}
onMouseUp={() => mouseUp(backFunc)}
/>
<Button icon={playing ? <PauseCircleOutlined /> : <PlayCircleOutlined />} onClick={play} />
<Button
icon={<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;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?