IE8及以下版本不识别HTML5语义标签和CSS3选择器,需用html5shiv注册标签、selectivizr模拟选择器,并将polyfill同步置于head中优先加载。
IE8及以下版本根本不会把 、、 这类标签当容器元素处理,CSS选择器 header { display: block; } 完全无效,DOM中也查不到这些节点的样式盒模型。
必须用 document.createElement() 主动“注册”新标签,否则连基本渲染都做不到。现代 polyfill 如 html5shiv 就是干这个的:
或延迟加载,必须同步执行且在 中尽早载入document.write 动态插入 HTML,html5shiv 可能失效,需改用 html5shiv-printshiv 版本、 等功能回填哪怕你写了 article > p:nth-child(2n),IE8 会直接忽略整条规则,连降级到通用样式都不会触发。这不是优先级问题,是解析器压根不认识这个语法。
这时候得靠 selectivizr 配合一个 JS CSS 库(如 IE7.js 或 jQuery)来模拟行为:
selectivizr 不支持 CSS 变量、@supports 或自定义伪类innerHTML 动态更新内容,新插入的元素不会自动应用选择器逻辑,需手动调用 selectivizr.refresh()
IE9 才开始支持 required、pattern 等属性,IE8 及以下连 都当普通文本框处理,更别说 form.checkValidity() 这类方法了。
不能只靠 polyfill 补接口,得换思路:用 JS 做前置校验 + 样式反馈,并禁用原生提交行为:
if (!('checkValidity' in document.createElement('form'))) {
document.addEventListener('submit', function(e) {
var form = e.target;
var email = form.querySelector('[type="email"]');
var isValid = email && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value);
if (!isValid) {
e.prev
entDefault();
email.classList.add('error');
email.focus();
}
});
}HTMLInputElement.prototype 加 checkValidity 方法——IE8 的 DOM 对象不是标准 JS 对象,无法安全扩展setCustomValidity 的提示文案无法通过 JS 注入到原生气泡中,只能用 title 属性或额外 显示很多项目把 polyfill 放在 底部,或者等 DOMContentLoaded 后再加载,这时 HTML 已解析完毕,语义标签早就被当成未知内联元素处理完了,html5shiv 再执行也晚了。
中,且在任何 CSS 和业务 JS 之前require.ensure 或动态 import()
html5shiv 的压缩版没删掉关键的 document.createElement 调用(有些 Uglify 配置会误删)最麻烦的是混合环境:比如某页面用 AngularJS 1.x + IE8,不仅得补 HTML5 标签,还得确保 ng-app 初始化前 polyfill 已就位,否则指令编译阶段就找不到父容器。