offsetTop && offsetParent
在迄今为止的一年里,做滚动动画的时候其实对一个概念比较模糊,就是一个元素在此文档中距离文档顶部的距离,一开始的想法是一个元素距离顶部的距离就是此元素同级的previous兄弟节点的高度和加上此元素的父元素的previous兄弟节点的高度和,这个想法我觉得是对的,但是一直没有去验证,而且因为没有验证我也一直把他作为求元素距顶部的距离的解法,直到我知道了offsetTop这个dom属性,一切都搞明白了,今天把这个说清楚。
首先看看offsetTop的解释
HTMLElement.offsetTop 为只读属性,它返回当前元素相对于其 offsetParent 元素的顶部的距离。
---MDN
这里有一个比较重要的概念其实是offsetParent,然后我们再看看offsetParent的解释
HTMLElement.offsetParent 是一个只读属性,返回一个指向最近的(closest,指包含层级上的最近)包含该元素的定位元素。如果没有定位的元素,则 offsetParent 为最近的 table, table cell 或根元素(标准模式下为 html;quirks 模式下为 body)。当元素的 style.display 设置为 "none" 时,offsetParent 返回 null。offsetParent 很有用,因为 offsetTop 和 offsetLeft 都是相对于其内边距边界的。
---MDN
其实就是说offsetParent就是距离他最近的一个具有定位属性的父元素,或者table元素或者display为table-cell的元素,所谓定位属性就是指position属性为fixed,或absolute,或relative的元素。所以根据这个我们可以很轻松的写出一个元素距离文档顶部的距离的方法:
/** * 环境:chrome * IE 不管,有兴趣自己调 */ function topPos( dom ){ let top= dom.offsetTop,baba= dom.offsetParent ; while( baba ){ let border = parseFloat( getStyle( baba,'border' ).match( /^(\d+)/ )[1] ) top += baba.offsetTop if( border != 0 && baba.offsetParent != null){//border 会漏算 top += border ; } baba = baba.offsetParent } return top; } function getStyle(obj,prop){ return window.getComputedStyle ? window.getComputedStyle(obj,null)[prop] : obj.currentStyle[prop]; }
恩 以上。
是有点麻烦哈!
来个大杀器:
getBoundingClientRect
返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合, 即:是与该元素相关的CSS 边框集合 。
- MDN
怎么用?
DOM.getBoundingClientRect().top;// 顶部距离
兼容性及详细用法:
https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect
知道了元素距离页面顶部的距离就可以做其他事情了,懒加载,左右联动,etc。恩 说完了。。。