一、为什么有的网站没有 <!DOCTYPE html>?
这不是技术失误,而是历史遗留 + 兼容老系统导致的:
-
超老网站/内网系统
很多 2000~2010 年的政府、企业、银行、OA、ERP 系统,当年就是按 IE 怪异模式 写的,一旦加
<!DOCTYPE>,页面布局、样式、JS 会直接崩掉,所以不敢加。 -
不敢重构
老系统能跑就不动,加 doctype 等于全页面返工,成本极高。
-
模板/框架默认没加
一些老旧后端模板(ASP、PHP 老框架)默认就不带 doctype。
结果 :没有 <!DOCTYPE html> → 浏览器强制进入怪异模式(Quirks Mode)
→ document.documentElement.clientHeight 直接变成页面总高度,不是视口。
二、怪异模式下:jQuery 如何正确获取视口高度?
我直接给你**最稳、兼容所有网站(含无 doctype)**的写法,你复制就能用。
1)jQuery 官方推荐:最稳写法(兼容怪异+标准模式)
js
// 无论页面有没有 doctype,这行永远返回 正确视口高度
var viewportHeight = $(window).height();
这就是答案 :
$(window).height() 内部自动做了怪异模式判断,你不用管页面有没有 doctype。
2)原生 JS 等价写法(你插件也能用)
如果你不想用 jQuery,原生这样写最兼容:
js
function getViewportHeight() {
return document.compatMode === 'CSS1Compat'
? document.documentElement.clientHeight // 标准模式
: document.body.clientHeight; // 怪异模式(无 doctype)
}
三、关键区别(一定要记住)
| 写法 | 标准模式 | 怪异模式(无 doctype) | 结论 |
|---|---|---|---|
$(window).height() |
✅ 视口 | ✅ 视口 | 永远正确 |
document.documentElement.clientHeight |
✅ 视口 | ❌ 页面总高度 | 会踩坑 |
document.body.clientHeight |
❌ 页面高度 | ✅ 视口 | 只对老页面有效 |
你遇到的问题 :
无 doctype → 怪异模式 → document.documentElement.clientHeight = 页面内容高度(错)
但 $(window).height() = 视口高度(对)
四、浏览器插件里终极方案
你是做插件的,我给你能直接丢进 content script的兼容代码:
如果你用 jQuery(最简单)
js
// 任何网站都能拿到正确视口高度
const vh = $(window).height();
如果你只用原生 JS(推荐,插件更轻量)
js
function getVHeight() {
return document.compatMode === 'BackCompat'
? document.body.clientHeight
: document.documentElement.clientHeight;
}
// 使用
const vh = getVHeight();
五、一句话总结
- 无
<!DOCTYPE>= 怪异模式 → 老系统为了兼容不敢加。 - jQuery 取视口高度永远用
$(window).height(),自动兼容所有模式。 - 原生就用
compatMode判断,两套逻辑都覆盖。
六、修复方案
- 把这段代码放在你插件里 jQuery 加载之后、业务代码之前
js
// 修复 jQuery 3.6 怪异模式下 $(window).height() 错误的 BUG
// 只需要在插件 content script 开头执行一次即可
(function($) {
// 保存原始的 height 方法
const originalHeight = $.fn.height;
// 重写 height
$.fn.height = function(value) {
// 如果是获取 window 高度,并且是怪异模式
if (arguments.length === 0 &&
this[0] === window &&
document.compatMode === 'BackCompat') {
// 怪异模式下直接返回正确视口高度
return window.innerHeight || document.body.clientHeight;
}
// 其他情况正常走原始逻辑
return originalHeight.call(this, value);
};
})(jQuery);