这几个概念实在是太难记了,而且经常搞不清它们的区别,我也懒得记了。我花了一下午时间整理了这些知识点,方便日后翻看。每个系列单独一篇文章,此篇主要讲述offset
。
下面的案例均在浏览器调试通过,图上的标记均是自己手动画,请君多包涵。
获取鼠标指针位置相对于
触发事件的对象
的 x 坐标和y坐标
比如我给div
元素注册了点击事件,在div内容区域点击,获取的就是相对于div内容区域的坐标,但一定要注意,如果点击区域是border区域那么就是相对于内容区域的负方向了。
注意:与clientX和cilentY的区别是,前者是相对于触发事件的对象的坐标,而后者是相对于浏览器可视区域的坐标。IE8不支持事件参数e,要想使用事件参数对象必须是window.event
css
div {
position: absolute;
left: 200px;
top: 50px;
width: 300px;
height: 250px;
background-color: blue;
border: 50px solid red;
margin: 100px;
padding: 10px;
}
js
var div = document.querySelector('div')
div.onclick = function(e) {
e = e || window.event // 兼容低版本IE 防止时间参数对象失效
console.log('offsetX:' + e.offsetX, 'offsetY: ' + e.offsetY)
}
谷歌 | 火狐 | IE10-11 | IE8-9 |
---|---|---|---|
正常 | 正常 | 正常 | 有小数 |
MDN:
offsetParent
是一个只读属性,返回一个指向最近的(closest,指包含层级上的最近)包含该元素的定位元素。如果没有定位的元素,则 offsetParent 为最近的 table, td, th或body元素。当元素的 style.display 设置为 “none” 时,offsetParent 返回 null。
简单概括一下:offsetParent
是某个元素最近的并带有positon
属性(默认值static除外)父级元素,如果这个父级元素没有position
属性,那么这个父级元素只能为最近的 table
, td
, th
或body
元素。
我们看上面的例子。div
这个元素最近的父级就是body了,虽然没有position属性,但是也满足上述条件。
我们给div外面加一层父级元素header,不加任何属性,返回的offsetParent
还是body元素。
再测试一下,我们给header元素加个position:
可以看到,offsetParent
返回的是header元素。我们再给header加个属性:display:none
:
此时发现:
到这里,我相信大家应该都明白了offsetParent的作用了吧,有了这个基础,下面几个属性就很好理解了。
在 Webkit 中,如果元素为隐藏的(该元素或其祖先元素的 style.display 为 “none”),或者该元素的 style.position 被设为 “fixed”,则该属性返回 null。(chrome浏览器内核是blink)
在 IE 9 中,如果该元素的 style.position 被设置为 “fixed”,则该属性返回 null。(display:none 无影响。)
它们都是只读属性,返回一个元素的布局宽度或高度。
宽度:width + padding + border + scrollbar(如果横向滚动条存在)
高度:height + padding + border + scrollbar(如果纵向滚动条存在)
注意:这个属性将会 round(四舍五入)为一个整数。如果你想要一个fractional(小数)值,请使用element.getBoundingClientRect().
谷歌 | 火狐 | IE8-11 |
---|---|---|
offsetWidth:420 offsetHeight: 370 | offsetWidth:419 offsetHeight: 369 | offsetWidth:420 offsetHeight: 370 |
总结:不同浏览器实现offsetwidth
和offsetHeight
属性存在差异,比如火狐浏览器少了一个像素。如果你了解CSS3的话,offsetwidth
和offsetHeight
其实和border-box的width和height是一样的。
它们是一个只读属性,返回当前元素左上角相对于 HTMLElement.offsetParent 节点的左边界偏移的像素值。
说到这里,我们上面提到的offsetParent
就派上用场了。
比如我们上面一直讲的例子。当前元素为div,它的offsetParent
返回body。那么div元素的offsetLeft 和 offsetTop值就是左上角相对于offsetParent
的距离。
offsetLeft = margin-left + left
offsetTop = margin-top + top
在浏览器控制台打印一下:
即使当前元素的父级有position,值也是一样的,因为它都是相对于父级。
谷歌 | 火狐 | IE8-11 |
---|---|---|
offsetLeft:300 offsetTop: 150 | offsetLeft:300 offsetTop: 150 | offsetLeft:300 offsetTop: 150 |
大部分浏览器均支持。
下篇文章讲述 client
系列,传送门在这:offset、client、scroll、screen、page五大系列的区别(二)
HTMLElement - Web API 接口参考 | MDN