dropzone属性已废弃且无可访问性支持,应改用dragover/drop事件配合tabindex="0"、aria-label和aria-live动态提示。
dropzone 属性本身不支持可访问提示文本
HTML 的
是个已被废弃的实验性属性,现代浏览器基本不支持,更不会读给屏幕阅读器听。它既不能触发语音朗读,也无法通过
或
补救——因为浏览器压根不把它当语义化交互区域处理。
常见错误现象:
写了但 NVDA/JAWS 完全没反应;用户用键盘 Tab 无法聚焦该区域;移动端也无拖拽反馈。
别再用
,它在 Chrome 81+、Firefox 90+ 已被移除
实际可用的替代方案是原生
/
事件 + 手动添加 ARIA 状态
必须配合
才能让键盘用户聚焦到拖拽区
怎么让拖拽区对屏幕阅读器“可说”
核心思路:用 ARIA 把拖拽区域声明为一个“有操作意图的控件”,并动态更新状态。不是靠属性“标注”,而是靠 JS 主动管理
和
(虽然后者已过时,但部分读屏仍识别)。
使用场景:文件上传卡片、编辑器内嵌拖拽区、表单附件区域。
立即学习
“
前端免费学习笔记(深入)
”;
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
初始状态加
或
+
监听
时设置
区域并插入提示:“松开鼠标即可上传”,然后立即清空(避免重复播报)
不要用
—— WAI-ARIA 1.2 已弃用,且 Safari VoiceOver 完全忽略
为什么不能只靠 CSS 视觉提示
视觉上的高亮、边框变色、动画,对屏幕阅读器用户等于不存在。他们依赖的是 DOM 结构、语义角色和实时状态变更。
性能/兼容性影响:纯 CSS 实现的
或
类名切换,会导致键盘焦点用户(比如按 Tab 进入该区域)完全得不到任何反馈,因为
样式没同步设计。
必须同时响应
、
、
、
四个事件
不要设为
,至少保留
用于键盘聚焦可见性
移动端没有
事件,得 fallback 到点击触发
并隐藏它
容易被忽略的边界情况
很多团队测完桌面 Chrome 就上线,结果盲人用户反馈“根本不知道那里能拖”。问题常出在几个静默失效点上。
父容器用了
,把动态插入的
提示元素裁掉了
被误加在拖拽区上,导致
根本不触发
用
隐藏文件 input,但没加
,导致读屏重复播报“选择文件按钮”两次
多语言站点没把提示文本塞进
或 i18n key,硬编码中文字符串
最麻烦的其实是「拖拽中途取消」——比如用户拖着文件划出区域又拖回来,这时候状态要能恢复,否则读屏会卡在“已就绪”而实际不可用。这事没法靠 HTML 属性解决,只能靠 JS 精确跟踪 drag 事件生命周期。
dropzonearia-labelaria-describedbydropzone="copy file://"dropzonedragoverdroptabindex="0"aria-livearia-dropeffectrole="application"role="region"aria-label="拖拽图片或 PDF 文件到这里上传"dragenteraria-live="polite"aria-dropeffect="copy"const dropArea = document.querySelector('.upload-drop');
dropArea.setAttribute('tabindex', '0');
dropArea.setAttribute('aria-label', '拖拽图片或 PDF 文件到这里上传');
dropArea.addEventListener('dragenter', () => {
const msg = document.getElementById('sr-msg') || document.createElement('div');
msg.id = 'sr-msg';
msg.className = 'sr-only';
msg.setAttribute('aria-live', 'polite');
msg.textContent = '松开鼠标即可上传';
document.body.appendChild(msg);
});:hoverdragover:focusfocusblurdragenterdragleaveoutlinenoneoutline: 2px solid #007affdragoverflow: hiddenaria-livepointer-events: nonedragenterdisplay: nonearia-hidden="true"data-i18n