在 HTML 的世界里,我们经常需要对文档或是其中的 DOM 的大小进行了解和控制,比如说以下这些场景。
- 获取或设置某个 DOM 的尺寸。
- 获取窗口内容的尺寸。
- 获取整个文档的尺寸。
- 将某个 DOM 的宽度,与窗口内容或是其它 DOM 进行可定义的关联绑定。
- 将某个 DOM 的高度,与窗口内容或是其它 DOM 进行可定义的关联绑定。
那么,如果说需要一套完整的工具,来支持这些场景,该如何是好呢?好吧,我们先从获取尺寸开始。为了方便起见,我们定义返回值为一个 JSON 对象,其中包含 width 和 height 两个属性,均为数字型,以表示宽度和高度。接下来,我们需要实现以下函数,并返回刚才定义的类型。
function getSize(element) {
if (!element) return null;
// ToDo: Implement it.
return null;
}
在这个函数里,传入参数 element 我们认为可能会是以下任意一种情形。
- 字符串,表示某一 DOM 的 ID。
- 网页文档元素。
- 窗口元素(即 window 对象)。
- 某一 body 内的 DOM 元素。
为此,我们开始逐一实现。针对字符串,我们先尝试着获取一下它对应的 DOM。
if (typeof element === "string")
element = document.getElementById(element);
if (!element) return null;
当然,你也可以把这个改成 query 而非 ID 的方式来获取。然后,针对文档,可以考虑测试以下属性。
- 如果有 body 属性,则可能为 HTML 文档对象。
- 如果有 documentElement 属性,则可能为 XML 文档对象。
然后再尝试获取其尺寸。
if (element.body || element.documentElement) {
var bodyWidth = !!document.body ? document.body.scrollWidth : 0;
var documentWidth = !!document.documentElement ? document.documentElement.scrollWidth : 0;
var bodyHeight = !!document.body ? document.body.scrollHeight : 0;
var documentHeight = !!document.documentElement ? document.documentElement.scrollHeight : 0;
return {
width: bodyWidth > documentWidth ? bodyWidth : documentWidth,
height: bodyHeight > documentHeight ? bodyHeight : documentHeight
}
}
而对于窗口元素(即 window 对象),其实只要判断有没有 parent 属性就好了。不过在获取宽度和高度的时候,需要进行一些兼容性处理。
if (element.parent) {
return {
width: document.compatMode == "CSS1Compat" ? document.documentElement.clientWidth : document.body.clientWidth,
height: document.compatMode == "CSS1Compat" ? document.documentElement.clientHeight : document.body.clientHeight
};
}
那么剩下的,我们就认为应该是 body 内的 DOM 元素对象了。
return {
width: element.offsetWidth,
height: element.offsetHeight
};
由此,获取部分就搞定了!接下来是对 DOM 元素的宽度和高度的设置了。我们预计会实现一个函数,允许传入3个参数,即该 DOM 元素、宽度和高度。其中,宽度或高度若为空,我们就认为不对其设置,否则的话,我们支持数字和字符串两种形式。因此有了一下初始化代码。
function setSize(element, width, height) {
if (!element) return null;
// ToDo: Implement it.
return null;
}
同样,对于参数 element 为字符串的情形,我们先做一个处理。
var ele = typeof element === "string" ? document.getElementById(element) : element;
if (!ele) return null;
然后,我们开始实现对宽度的设置。我们可以简单的通过对内联样式的设置来实现。
if (width != null) ele.style.width = typeof width === "string" ? width : (width.toString() + "px");
同理,高度设置也是如此。
if (height != null) ele.style.height = typeof height === "string" ? height : (height.toString() + "px");
最后返回设置后的尺寸。
return {
width: ele.offsetWidth,
height: ele.offsetHeight
};
如此就完成了。接下来,我们还需要增加一些函数,以支持诸如宽度和高度的绑定功能,这在界面自适应方面尤为有用,所以,还是敬请期待下一篇文章啦。
【未完待续】
文章类型及复杂度:Web 前端开发进阶。
节选翻译自 MSDN 博文 Get and set DOM size,内容有所调整。
http://blogs.msdn.com/b/kingcean/archive/2016/04/14/dom-size.aspx