长按按钮反应
Long Press button in react
这可能真的很简单,但任何人都知道如何在 React 中制作长按按钮。就像一个按钮,如果你按住它 2 秒,它就会被“点击”,否则就不会。是否有反应鼠标事件?也许我以某种巧妙的方式使用了 onMouseDown 事件?
您可以尝试的一种技巧是记下 'onMouseDown' 事件触发的时间,并记下 'onMouseUp' 事件触发的时间。
如果这些时间之间的差异大于等于 2 秒,您可以执行您想要的操作。
您必须在 'onMouseUp' 事件触发时执行的方法中编写逻辑来检查时差和要执行的代码。
delay = 2000;
startPress = null;
function mouseDown() {
startPress = Date.now();
}
function mouseUp() {
if(Date.now() - startPress > delay)
{
// your code
}
}
我使用以下方法创建了一个按钮,当您按住该按钮时,该按钮会动态变化 class。使用 setInterval
而不是 setTimeout
可以简化操作,因为我们自己管理结束计数。我们不做任何类型的 DateTime 计算,我们可以通过观察 currentCount
.
主动监控当前延迟毫秒数
我使用 DaisyUI 作为我的组件框架,但是任何 CSS classes 都可以使用。
import { useCallback, useEffect, useRef, useState } from 'react';
export type LongPressButtonProps = {
/** Text that will appear within the button */
buttonText: string;
/** Function to run once delay has been exceeded */
onExecute: () => void;
/** How long should be button be held before firing onExecute */
delayMs: number;
/** How frequently should the count be updated */
refreshMs: number;
};
const LongPressButton = ({
delayMs,
onExecute,
buttonText,
refreshMs = 100,
}: LongPressButtonProps) => {
const [mouseDown, setMouseDown] = useState(false);
const [currentCount, setCurrentCount] = useState(0);
const intervalRef = useRef<NodeJS.Timer>();
const [buttonClass, setButtonClass] = useState('btn-primary');
const onInterval = useCallback(() => {
setCurrentCount((c) => c + refreshMs);
}, [setCurrentCount, refreshMs]);
useEffect(() => {
if (mouseDown) intervalRef.current = setInterval(onInterval, refreshMs);
if (!mouseDown && intervalRef.current) {
clearInterval(intervalRef.current);
setCurrentCount(0);
setButtonClass(`btn-primary`);
}
}, [onInterval, delayMs, mouseDown, refreshMs]);
useEffect(() => {
if (currentCount > 0) setButtonClass(`btn-error`);
if (currentCount > delayMs) {
onExecute();
setCurrentCount(0);
}
}, [currentCount, delayMs, onExecute]);
return (
<button
className={`btn ${buttonClass}`}
onMouseDown={() => setMouseDown(true)}
onMouseUp={() => setMouseDown(false)}
onMouseLeave={() => setMouseDown(false)}
onTouchStart={() => setMouseDown(true)}
onTouchEnd={() => setMouseDown(false)}
style={{ transition: `${delayMs}ms` }}
>
{buttonText}
</button>
);
};
export default LongPressButton;
这可能真的很简单,但任何人都知道如何在 React 中制作长按按钮。就像一个按钮,如果你按住它 2 秒,它就会被“点击”,否则就不会。是否有反应鼠标事件?也许我以某种巧妙的方式使用了 onMouseDown 事件?
您可以尝试的一种技巧是记下 'onMouseDown' 事件触发的时间,并记下 'onMouseUp' 事件触发的时间。
如果这些时间之间的差异大于等于 2 秒,您可以执行您想要的操作。
您必须在 'onMouseUp' 事件触发时执行的方法中编写逻辑来检查时差和要执行的代码。
delay = 2000;
startPress = null;
function mouseDown() {
startPress = Date.now();
}
function mouseUp() {
if(Date.now() - startPress > delay)
{
// your code
}
}
我使用以下方法创建了一个按钮,当您按住该按钮时,该按钮会动态变化 class。使用 setInterval
而不是 setTimeout
可以简化操作,因为我们自己管理结束计数。我们不做任何类型的 DateTime 计算,我们可以通过观察 currentCount
.
我使用 DaisyUI 作为我的组件框架,但是任何 CSS classes 都可以使用。
import { useCallback, useEffect, useRef, useState } from 'react';
export type LongPressButtonProps = {
/** Text that will appear within the button */
buttonText: string;
/** Function to run once delay has been exceeded */
onExecute: () => void;
/** How long should be button be held before firing onExecute */
delayMs: number;
/** How frequently should the count be updated */
refreshMs: number;
};
const LongPressButton = ({
delayMs,
onExecute,
buttonText,
refreshMs = 100,
}: LongPressButtonProps) => {
const [mouseDown, setMouseDown] = useState(false);
const [currentCount, setCurrentCount] = useState(0);
const intervalRef = useRef<NodeJS.Timer>();
const [buttonClass, setButtonClass] = useState('btn-primary');
const onInterval = useCallback(() => {
setCurrentCount((c) => c + refreshMs);
}, [setCurrentCount, refreshMs]);
useEffect(() => {
if (mouseDown) intervalRef.current = setInterval(onInterval, refreshMs);
if (!mouseDown && intervalRef.current) {
clearInterval(intervalRef.current);
setCurrentCount(0);
setButtonClass(`btn-primary`);
}
}, [onInterval, delayMs, mouseDown, refreshMs]);
useEffect(() => {
if (currentCount > 0) setButtonClass(`btn-error`);
if (currentCount > delayMs) {
onExecute();
setCurrentCount(0);
}
}, [currentCount, delayMs, onExecute]);
return (
<button
className={`btn ${buttonClass}`}
onMouseDown={() => setMouseDown(true)}
onMouseUp={() => setMouseDown(false)}
onMouseLeave={() => setMouseDown(false)}
onTouchStart={() => setMouseDown(true)}
onTouchEnd={() => setMouseDown(false)}
style={{ transition: `${delayMs}ms` }}
>
{buttonText}
</button>
);
};
export default LongPressButton;