必须使用实现“加入购物车”,显式声明type、data-product-id和data-sku-id;按钮需独立放置、禁用时同步设置disabled与aria-busy;触控区不小于44×44px且避免嵌套交互。

按钮必须用 ,不能用 @#@#@#@#@#@#@#@#@#@0(破坏语义、触发 hash 变化)
按钮要放在卡片最外层容器内,但不能嵌套在 或 里
卡片结构常用 更隐蔽的问题是:如果卡片本身用了 iPhone 和 Android 都要求最小可触控区域为 44×44 CSS 像素,否则 WCAG 不合规,用户实际点击容易误操作。光给按钮加 可靠方案是设 生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力:
- 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面;
- 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”;
- 提及位于 `apps/console/src/featur 用户连点、网络延迟、接口重复调用——这些都会让纯样式切换(比如加 恢复时别只删 class,优先还原 DOM 属性。失败后建议保持按钮启用,弹出简短提示(如“库存不足”),而不是留着 loading 状态让用户干等。
按钮嵌入卡片这事,表面是 HTML 结构问题,实际是交互责任划分问题:谁响应点击、谁管理状态、谁暴露语义。最容易被忽略的是 或语义清晰的 或 内部,会触发嵌套交互冲突,部分浏览器直接忽略事件。onclick(比如整卡跳转详情页),再在内部放一个按钮,就可能因事件冒泡或捕获顺序错乱,导致加购失败或误跳转。稳妥做法是只在一个层级响应交互:要么整卡可点(跳详情),要么按钮单独可点(加购),二者不共存。
...
if (e.target.matches('button[data-action="add"]')) { ... }
移动端触控区至少
44×44px,别靠 padding 硬撑padding: 12px 不够——如果按钮是 inline-block 或 display: inline,换行符产生的空白间隙会让真实宽度缩水;若父容器有 font-size: 0 或 letter-spacing 干扰,也会压缩尺寸。display: block 或 inline-flex,再用 min-width: 44px; min-height: 44px; 强制保底。同时检查是否意外设置了 pointer-events: none(比如被遮罩层覆盖)、或父级 overflow: hidden 裁掉了热区。
button[type="button"] { display: block; min-width: 44px; min-height: 44px; margin: 0 auto; }
span { padding: 12px; } (span 不是交互元素,且 padding 不扩大 button 热区)width/height 是否 ≥44,以及 pointer-events 是否为 auto
按钮状态要靠 JS 控制
disabled 和 aria-busy,不能只切 CSS 类.loading 类)失效。真正可靠的禁用逻辑是:点击瞬间执行 button.disabled = true,请求完成后再设 false;同时用 aria-busy="true" 向屏幕阅读器声明“正在处理”,比仅靠视觉反馈更健壮。
button.disabled = true; button.setAttribute('aria-busy', 'true');
button.disabled = false; button.removeAttribute('aria-busy');
button.classList.add('loading'); setTimeout(() => button.classList.remove('loading'), 1000);(没控 disabled,没管 aria,时间写死)aria-busy 和 disabled 的同步时机——很多项目只在 UI 层做 loading,却忘了 DOM 层和辅助技术层也得同步更新。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










