上下文菜单和快速操作
1)目的和范围
上下文菜单和快速操作缩短了常用操作的路径:- 对对象的本地操作(卡,表行,系数)。
- 分配上的批处理操作。
- 隐藏但不关键选项(次要选项)。
- 规则:关键和主要动作不要只隐藏在上下文菜单中。
2)触发器和选项
右点击/Shift+F10/菜单密钥是经典的上下文。
Icon button(kebab '⋮',meatballs'……',context)是通用的tach/desktop。
Long-press(400-600 ms)是相当于right click的移动设备。
Command palette (⇧⌘P/Ctrl+K)-全球快速搜索命令。
Swipe-reveal (iOS/Android列表)-打开一系列快速短裤。
建议:至少提供两种调用方式(图标+上下文点击/键)。
3)内容和优先级
前1-3点-频繁行动;然后是分隔符;接下来-较少使用。
破坏性的-在结尾,标有颜色/图标(通常通过确认/undo标记)。
措辞是动词+宾语("添加到收藏夹","复制ID")。
标签仅≠图标:图标是放大器,不是文本替换。
4)分组和状态
Состояния: `disabled`, `checked` (`menuitemcheckbox`/`menuitemradio`), `destructive`.
逻辑块的分隔符(查看、编辑、管理、危险)。
如果混淆,我们不会显示角色无法访问;或者-我们显示为带有原因提示的"失衡"。
5)可用性(A11y)
容器:'role='menu',元素:'role='menuitem'/'menuitemcheckbox'/'menuitemradio'。
Roving tabindex:当前元素上的单个"tabindex="0",其余的"-1"。
↑↓箭头-移动,→/←箭头-从子菜单登录/退出。Enter/Space-激活,Esc-关闭。
Typeahead:打印第一个字母将焦点转移到点。
焦环可见;AA ≥文本和图标的对比。
对于按钮图标,请使用"aria-haspopup="menu"和"aria-expanded"。
html
<button id="more" aria-haspopup="menu" aria-expanded="false" aria-controls="menu-1">Еще</button>
<ul id="menu-1" role="menu" aria-labelledby="more" hidden>
<li role="menuitem" tabindex="0">Открыть</li>
<li role="menuitem">Скопировать ссылку</li>
<li role="menuitemcheckbox" aria-checked="true">В избранном</li>
<li role="menuitem" data-danger="true">Удалить</li>
</ul>
导航(roving tabindex方案):
js const menu = document.getElementById('menu-1');
menu.addEventListener('keydown', e=>{
const items=[...menu.querySelectorAll('[role^="menuitem"]')];
let i=items.findIndex(n=>n.tabIndex===0);
if(e.key==='ArrowDown'){ items[i].tabIndex=-1; items[(i+1)%items.length].tabIndex=0; items[(i+1)%items.length].focus(); e.preventDefault(); }
if(e.key==='ArrowUp'){ items[i].tabIndex=-1; items[(i-1+items.length)%items.length].tabIndex=0; items[(i-1+items.length)%items.length].focus(); e.preventDefault(); }
if(e.key==='Escape'){ menu.hidden=true; document.getElementById('more').focus(); }
});
6)定位和表演
从源位置打开菜单(点击点/图标),移位4-8 px;观察屏幕边缘(flip/shift)。
门户/层顶部("z-index")与点击捕捉关闭。
懒惰地渲染,在长菜单中回收列表(不需要虚拟化,但要避免数百个项目)。
动画仅为"opacity/transform",持续时间为140-200毫秒(超出:100-160毫秒)。
在"ArrowRight"上打开子菜单并以80-120毫秒的延迟(反闪光灯)旋转。
7)移动模式
带有触觉的长新闻;450 ± 100毫秒的时间。
底部表作为上下文菜单的一种形式(thumb-reachable)。
清单中的Swipe操作:左侧为"存档/选中",右侧为"删除"(确认/undo)。
点击区域≥ 44 × 44,签名简短,图标为20-24 px。
8)确认、undo和安全
破坏性活动:第二次确认(modal/confirm模式)或undo 5-10 s。
财务/风险-通过具有后果背景的显式匹配。
显示"Disabled"的原因("不够正确","达到极限")。
9)快速行动没有菜单
行中的直线短裤(图标"",",","⋯")。
Hover-reveal(桌面):在悬停时显示动作,但也留下明显的触发器。
Command palette:按动作搜索,线索中的热键("⌘S","Ctrl+Enter")。
10)文桉写作和图标
动词+宾语,2-3个单词。
从动作("删除条目……")开始,不从名词("删除条目")开始。
来自单个集合的图标;使用相同的图标在整个产品中执行相同的操作。
模棱两可的句子的解释提示("标题"/tooltip)。
11)遥测与实验
点的CTR,从打开到点击的时间中位数,取消频率/undo。
不合时宜的数量(破坏性→取消)。
A/B:项目的顺序和分组,名单上有快速短裤。
"隐形"项目的逻辑(没有人使用)是删除/转移的候选人。
12)设计系统令牌(示例)
json
{
"menu": {
"minWidth": 208,
"itemHeight": 36,
"gap": 4,
"padding": 8,
"radius": 12,
"elev": 8,
"anim": { "inMs": 180, "outMs": 120, "ease": "cubic-bezier(0.2,0,0.2,1)" }
},
"swipe": { "revealThresholdPx": 56, "confirmDestructive": true }
}
CSS预设:
css
.menu{min-width:208px;padding:8px;border-radius:12px;box-shadow:var(--elev-3);background:var(--bg-elevated)}
.menu [role^="menuitem"]{height:36px;padding:0 12px;display:flex;gap:8px;align-items:center;border-radius:10px}
.menu [role^="menuitem"]:hover,
.menu [role^="menuitem"][tabindex="0"]{background:var(--bg-hover)}
.menu [data-danger="true"]{color:var(--role-danger)}
13)按组件分列的模式
卡/瓷砖:右上角的"⋯"图标;在hover-显示,在tach-始终可见。
表中的行:最后一栏中的"⋯";多重突出显示-顶部/底部批处理操作面板。
聊天/通知列表:带有undo的swipe-actions(存档/阅读/删除)。
媒体画廊:长时间脱落→多重选择模式+底部动作面板。
14) iGaming的细节
快速投注(quick bet):在因子快捷菜单中,"放置X"(预建)、"添加到优惠券"、"订阅更改因子"。确认/undo是强制性的。
选择/订阅:"添加提供商/游戏到收藏夹","订阅锦标赛"。
高速缓存:具有在线确认和当前总和;仅在市场状态下可用。
节制/记者:"抱怨","阻止聊天"-安全,通过角色可见。
负责任的游戏:"设置限制","24小时暂停"-没有侵略性的颜色,并清楚地描述了后果。
15)反模式
关键操作仅隐藏在上下文菜单中。
没有文本的项目(一些图标),尤其是在列表中。
在切换到子菜单时意外关闭游标离开(没有延迟/走廊)。
菜单与源项重叠或离开屏幕(无flip/shift)。
没有确认的破坏性/undo。
非明显权利(该条款在没有解释的情况下失踪)。
16) QA支票清单
可用性
- 'role="menu"/"menuitem"是正确的,roving tabindex和箭头工作。
- Esc关闭菜单,焦点返回到源。
- 对比度和焦环对应于AA。
行为行为
- 项目的顺序应反映频率和风险;破坏性的。
- 定位考虑边缘(flip/shift);快速动画(≤ 200毫秒)。
- 子菜单在ArrowRight上打开,不发抖(hover-intent 80-120 ms)。
移动设备
- 具有触觉的长新闻;bottom-sheet用拇指舒适。
- Swipe-actions具有undo;集团区域≥ 44 × 44。
安全性
- 危险行为的确认/放弃;无法解决的原因是可以理解的。
- 线索/标签中没有泄露的私人数据。
度量标准
- 由CTR/点击前的时间拍摄;misclick/undo监控。
17)实现: 开放/关闭和点击关闭
js const btn=document.getElementById('more'), menu=document.getElementById('menu-1');
const open=()=>{ menu.hidden=false; btn.setAttribute('aria-expanded','true'); menu.querySelector('[role^="menuitem"]').focus(); };
const close=()=>{ menu.hidden=true; btn.setAttribute('aria-expanded','false'); btn.focus(); };
btn.addEventListener('click', e=>{ menu.hidden?open():close(); });
document.addEventListener('pointerdown', e=>{ if(!menu.hidden &&!menu.contains(e.target) && e.target!==btn) close(); });
window.addEventListener('blur', close);
18)设计系统中的文档
Компоненты: `ContextMenu`, `MenuItem`, `Submenu`, `BottomSheet`, `SwipeAction`, `CommandPalette`.
行大小/高度/半径/动画令牌。
Gaids可用性(ARIA,键盘,typeahead)。
带有分组,定位和确认示例的"Do/Do n't"。
简短的摘要
上下文菜单和快速操作可在可预测,可访问且安全的情况下加快操作:两个通话路径,带有图标的清晰标签,合理的分组,风险确认/undo,正确的键盘导航和清晰的定位。在设计系统中记录令牌和模式-用户将迅速采取行动,而不必担心错误。