今日在复习可视化尺寸获取时突发奇想,为什么要在怪异模式下使用document.body.clientWidth
,在标准模式下使用document.documentElement.clientWidth
?以及是否在IE8及以下的版本中其中一个获取方式将返回undefined
或0
。
出于该问题的思考,有了以下代码的测试,在这里我尝试还原IE8以下
的IE浏览器版本(通过Edge浏览器的仿真IE),结果是三个方法都有返回值,好似不存在兼容性的问题。 但当我给他们设置边界条件时发现不同模式下总会有一个方法返回值会出现问题。
怪异模式下的document.documentElement.clientWidth
、标准模式下的document.body.clientWidth
无法获取到可视窗口的真实尺寸。
一、为什么怪异模式下使用body.clientWidth
经过测试,在怪异模式下使用document.documentElement.clientWidth
无法正确的获取到可视窗口的真实宽度,得到的结果为当前窗口中HTML元素的真实宽度,假设当前的可视窗口宽度为1350px
,HTML元素的真实宽度为500px
,那么在怪异模式(BackCompat)下使用document.documentElement.clientWidth
方法所得到的值将为500px
,而不是1350px
。因此在怪异模式下使用的是document.body.clientWidth
方法获取可视化区域宽度。
至此问题解决,但在使用document.body.clientWidth
的前提下我们需要注意一点:document.body.clientWidth
方法获取的宽度不包含滚动条的宽度。
二、为什么标准模式下使用documentElement.clientWidth
相同的道理,在标准模式下使用document.body.clientWidth无法正确获取到可视化窗口的真实宽度。值得提的一点是不管在标准模式、怪异模式下,使用window.innerWidth
方法都能正确的获取到正确的且包含滚动条宽度的可视化区域宽度,因此当浏览器兼容该方法时应当优先使用。
三、测试代码
前提条件:在CSS中将html、body两个元素的宽高设置为5000px
、清除margin、padding
。
1. 标准模式测试
默认的HTML就是处于标准渲染模式(CSS1Compat),根据下列的代码我们可以在页面上看到window.innerWidth
、document.documentElement.clientWidth
方法可以正确的得到可视宽度,且可以看出document.documentElement.clientWidth
方法并没有将滚动条宽度纳入计算。而document.body.clientWidth
则是获取到了body
元素的真实宽度。
/**
* IE8/IE9以下无法直接使用window.innerWidth、window.innerHeight获取可视区域尺寸
* 此时与滚动条滚动距离获取类似,我们将从body、html元素上获取页面的宽度、高度
* 此时将出现一个渲染概念(标准模式、怪异模式)
* 我们可以通过document.compatMode来获取到当前的渲染模式
* 1. backCompat:怪异模式
* 2. CSS1Compat:标准模式或准标准模式(如今的模式已经标准化,准标准模式失去意义)
* 在怪异模式下
*/
document.writeln(
`${
document.compatMode === "CSS1Compat" ? "标准模式" : "怪异模式"
}下通过body获取的可视窗口宽度为: ${document.body.clientWidth}<br/>`
);
document.writeln(
`${
document.compatMode === "CSS1Compat" ? "标准模式" : "怪异模式"
}下通过body获取的可视窗口高度为: ${document.body.clientHeight}<br/>`
);
document.writeln(
`${
document.compatMode === "CSS1Compat" ? "标准模式" : "怪异模式"
}下通过documentElement获取的可视窗口宽度为: ${
document.documentElement.clientWidth
}<br/>`
);
document.writeln(
`${
document.compatMode === "CSS1Compat" ? "标准模式" : "怪异模式"
}下通过documentElement获取的可视窗口高度为: ${
document.documentElement.clientHeight
}<br/>`
);
效果如下:
2. 怪异模式测试
想要将浏览器的渲染模式修改为怪异模式,我们可以修改HTML文件的文档类型,如下代码所示,将<!DOCTYPE html>
修改为<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
。
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<!-- <!DOCTYPE html> -->
测试效果如下:
从验证的结果中我们能够明确的发现两个方法在不同模式下可能遇到的问题,因此在封装可视化尺寸获取方法考虑兼容性问题时,应该注意到这一点。
四、可视尺寸兼容性方法封装
我们可以对可视化尺寸进行简单的兼容性封装:
function getClientSize(){
if (window.innerWidth) {
return {
width: window.innerWidth,
height: window.innerHeight
}
}
/**
* 具体见MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/compatMode
* backCompat 怪异模式
* CSS1Compat 标准模式
* */
else if (document.compatMode === 'backCompat') {
return {
width: document.body.clientWidth,
height: document.body.clientHeight
}
} else {
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight
}
}
}