html全局属性中,data-、hidden、contenteditable和spellcheck在ie8–ie11及旧版edge存在兼容断层:data-需用getattribute()读取,hidden仅css隐藏不移除dom,contenteditable在safari/edge光标行为异常,spellcheck在各浏览器默认值与触发时机不一致。

HTML全局属性在不同浏览器中基本一致,但data-*、hidden、contenteditable和spellcheck四类属性存在明确兼容断层,尤其在IE8–IE11和旧版Edge中行为异常或完全不支持。
IE8–IE11中data-*属性必须用getAttribute()读取
IE8–IE11不支持dataset API,el.dataset.userId会返回undefined,即使data-user-id="123"已正确写入。更隐蔽的是:动态添加的data-*属性(如el.setAttribute('data-loaded', 'true'))在IE中不会自动同步到dataset对象,但getAttribute('data-loaded')始终有效。
- 统一读取方式:
el.getAttribute('data-user-id'),不要依赖dataset做兼容判断 - 写入可用
setAttribute,但避免混合使用dataset.xxx = yyy和setAttribute,IE中可能丢失 - Edge 17–18(EdgeHTML)也存在同样问题,不能靠
if ('dataset' in el)安全判断
hidden属性在IE9–IE11中仅支持CSS级隐藏,不触发DOM移除逻辑
hidden是布尔属性,语义上等价于display: none,但IE9–IE11只实现其CSS效果,不参与Aria可访问性树更新,也不影响offsetParent或getBoundingClientRect()的计算逻辑——它只是“看不见”,不是“不存在”。IE8及以下则完全忽略该属性。
- 若需真实移除交互能力,必须配合
aria-hidden="true"+tabindex="-1" - 检测是否生效别用
el.hidden,IE9+虽有该属性但值恒为false;改用window.getComputedStyle(el).display === 'none' - 服务端渲染时,IE用户看到
hidden标签仍会下载图片/脚本,无法节省资源
contenteditable在Safari和旧版Edge中光标与选区行为不一致
Safari 14–15对contenteditable内嵌<img>或<input>时,双击选区会意外跳转或丢失焦点;旧版Edge(EdgeHTML)中按Enter插入换行后,光标可能卡在段落末尾无法继续输入。这些不是语法错误,而是编辑引擎底层差异。
- 禁用默认回车行为:
el.addEventListener('keydown', e => { if (e.key === 'Enter') e.preventDefault(); }),再手动插入<div></div> - 图片/表单控件外层加
unselectable="on"(IE/Edge专用)或user-select: none(现代浏览器) - 避免在
contenteditable里直接放<script></script>或<iframe></iframe>,Safari会静默剥离
spellcheck属性在Firefox和Chrome中默认值不同且不可靠
Chrome默认开启spellcheck(值为true),Firefox默认关闭(false),且两者对contenteditable元素的拼写检查触发时机完全不同:Chrome在失焦后检查,Firefox在输入过程中实时标记。IE全系不支持该属性。
- 显式声明比依赖默认更可控:
<textarea spellcheck="false"></textarea>或<div contenteditable spellcheck="true"> <li>不要用<code>spellcheck做功能开关——它不控制语法高亮、自动更正或词典加载,只是提示浏览器“可以检查” - 移动端WebView(如微信内置浏览器)通常无视
spellcheck,改用inputmode="text"或autocorrect="off"更实际
真正麻烦的不是属性本身不被识别,而是同一属性在不同引擎中“生效路径”不同:有的走渲染层,有的走编辑器层,有的只走Aria层。没出错不等于没风险,尤其当data-*用于状态同步、hidden用于条件渲染时,细微差异会层层放大。











