跟DOM一样,BOM其实也是由很多的API组成。 不过对于BOM来说,最痛苦的不是不记得API,而是明明记得这个这个API,却没有考虑到它的兼容性。
之前的文章中讲到了offset系列的属性,他的宽高是由border,padding和width组成的。而它的offsetLeft和offsetTop则是相对于offsetParent的距离。这里的offsetParent指的是子盒子有定位的父级元素,而如果子盒子没有有定位的父级元素,那么它的offsetParent就是body。讲过了offset系列的,就该讲讲scroll系列的了。
首先就来说说scrollWidth和scrollHeight这两个属性分别获取的是元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #box { width: 100px; height: 100px; border: 5px solid red; padding: 10px;; } </style> </head> <body> <div id="box"> 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 啦啦啦 </div> <script> var box = document.getElementById("box"); console.log(box.scrollHeight); console.log(box.offsetHeight); </script> </body> </html>
上述代码分别输出了div的scrollHeight和offsetHeight,在控制台中,这两个属性打印的值分别是297和130;第二个值没有问题,他就是盒子上下边框宽加上下内边距加高度后得来的。而第一个值,获取的则是撑开之后的大小。可能对于这个值具体的算法有疑问,不过,在实际开发中一般不会出现有很大的内边距和边框时要你使用scrollHeight值的。所以不必太纠结为什么是这个数值,我们只要知道这个数值是随着内容的改变而改变就好了。scrollHeight值得算法是如果内容区域小于上下内边距加高度,那么它的值就是上下内边距加高度,否则就是内容撑开的高度。scrolltLeft也是同理。
而说完了scrollHeight和scrollLeft之后,就该来说说scrollTop和scrollLeft了,这两个值的用法相同。所以就来说说其中的offsetTop;一般来说,这两个属性都会配上鼠标移动事件来使用。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #box { width: 100px; height: 100px; overflow: auto; } </style> </head> <body> <div id="box"> 老王走了 老王走了 老王走了 老王走了 老王走了 老王走了 老王走了 老王走了 老王走了 老王走了 老王走了 老王走了 老王走了 老王走了 老王走了 </div> <script src="common.js"></script> <script> var box = my$("box"); box.onscroll = function () { console.log(box.scrollTop); } </script> </body> </html>
上述代码在拉动滚动条的时候执行,输出div的scrollTop。scrollTop显示的是内容区域向上移动的距离。
上面的代码获取的只是那个小的div中的滚动事件,那么如果在页面中呢?我们就可以把整个页面看做是一个div。这时候就遇到一个问题了,页面到底是body呢,还是html呢?其实,不同的浏览器有不同的解析方式。这时候,我们就要封装兼容性代码了。
function scroll() { return { scrollLeft:document.body.scrollLeft || document.documentElement.scrollLeft, scrollTop:document.body.scrollTop || document.documentElement.scrollTop }; }
在这里,我们封装了一个scroll函数,用来返回一个对象,这个对象有两个属性,这两个属性在调用的时候可以获取页面的滚动距离,并且,如果浏览器是根据body来获取或者根据html来获取他都能兼容。