此组件通过触发
context menu
事件在桌面设备上显示下拉菜单。是否可以在触摸设备上使用此下拉组件,但不使用 context menu
事件,而是使用 long press
显示下拉列表?触摸设备上没有 context menu
事件。
我想用
技术显示下拉菜单。long press
import React from 'react';
import type { MenuProps } from 'antd';
import { Dropdown, theme } from 'antd';
const items: MenuProps['items'] = [
{
label: '1st menu item',
key: '1',
},
{
label: '2nd menu item',
key: '2',
},
{
label: '3rd menu item',
key: '3',
},
];
const App: React.FC = () => {
const {
token: { colorBgLayout, colorTextTertiary },
} = theme.useToken();
return (
<Dropdown menu={{ items }} trigger={['contextMenu']}>
<div
style={{
color: colorTextTertiary,
background: colorBgLayout,
height: 200,
textAlign: 'center',
lineHeight: '200px',
}}
>
Right Click on here
</div>
</Dropdown>
);
};
export default App;
我尝试用额外的 div 包裹内容并在其上应用触摸事件。这是正确的方法还是可能有一些内置的解决方案?
<div
onTouchStart={handleTouchStart}
onTouchEnd={handleTouchEnd}
onContextMenu={e => e.preventDefault()}
>
Right Click on here or Long Press on Touch Devices
</div>
当触发器设置为
contextMenu
时,下拉菜单将 4 个道具传递给它的子级
我尝试使用pointerDown和pointerUp事件而不是onTouchEvent(antd抛出错误。可能是onTouchEvent中缺少某些字段/值)。您可以使用指针向下和向上事件来检测长按并调用 onContextMenu 函数来打开上下文菜单。
完整代码如下:
import type { MenuProps } from 'antd';
import { Dropdown, theme } from 'antd';
import type React from 'react';
import { type ForwardedRef, forwardRef, useRef } from 'react';
const items: MenuProps['items'] = [
{
label: '1st menu item',
key: '1'
},
{
label: '2nd menu item',
key: '2'
},
{
label: '3rd menu item',
key: '3'
}
];
const App: React.FC = () => {
return (
<Dropdown menu={{ items }} trigger={['contextMenu']}>
<Content />
</Dropdown>
);
};
export default App;
interface ContentProps {
onClick?: () => void;
onContextMenu?: (e: React.MouseEvent) => void;
className?: string;
// if disabled is true, onContextMenu and onClick events are not available
disabled?: boolean;
}
const Content = forwardRef((props: ContentProps, ref: ForwardedRef<HTMLDivElement>) => {
const { onContextMenu, className, disabled } = props;
const {
token: { colorBgLayout, colorTextTertiary }
} = theme.useToken();
const timer = useRef<ReturnType<typeof setTimeout>>(null);
const clearTimer = () => {
if (timer.current) {
clearTimeout(timer.current);
timer.current = null;
}
};
return (
<div
ref={ref}
style={{
color: colorTextTertiary,
background: colorBgLayout,
height: 200,
textAlign: 'center',
lineHeight: '200px'
}}
className={className}
onContextMenu={onContextMenu}
onPointerDown={(e) => {
if (disabled || e.pointerType !== 'touch') {
return;
}
// Clear timer if it is already running
clearTimer();
timer.current = setTimeout(() => {
onContextMenu?.(e);
clearTimer();
}, 2000);
}}
onPointerUp={clearTimer}
>
Right Click on here or Long Press on Touch Devices
</div>
);
});