元素几何属性(offsetLeft/Top...)和事件属性

762 阅读4分钟

说明

大多数几何属性只可读,可写属性已特别标出。

offset

offsetWidth/Height

以像素返回元素的占位宽度。包括内边距、垂直滚动条(如果有)、边框,但不包括外边距。

offsetWidth = width + padding + border + scroll

offsetLeft/Top

相对于最近的祖先元素

  • CSS 定位的(positionabsoluterelativefixed),
  • <td><th><table>
  • <body>

使用递归来获取相对于文档的左上角位移

//用offsetLeft和offsetTop来计算e的位置
function getElementPosition(e){
    var x = 0,y = 0;
    while(e != null) {
        x += e.offsetLeft;
        y += e.offsetTop;
        e = e.offsetParent;
    }
    return {
        x : x,
        y : y
    };
}

相对于文档

其他元素则返回的是相对于文档的左上角位移

client

clientWidth/Height

以像素返回元素内部宽度。包括内边距,但不包括垂直滚动条(如果有)、边框和外边距。

clientWidth = width + padding

对于类似 <i>、<code>、<span> 等内联元素,总是返回 0

clientLeft/Top

返回元素的内边距的外边缘和他的边框的外边缘的水平距离和垂直距离,通常这些值等于边框宽度。

在有滚动条时,并且浏览器将这些滚动条放置在左侧或顶部(操作系统为阿拉伯语或希伯来语),clientLeft 和 clientTop 还包含这些滚动条的宽度。

scroll

scrollWidth/Height

这两个属性是元素的内容区域加上内边距,在加上任何溢出内容的尺寸。

如果没有溢出时,这些属性与 clientWidth 和 clientHeight 是相等的。

scrollWidth = width + padding+溢出部分

scrollLeft/Top(可写)

指定的是元素的隐藏、滚动部分的 width/height。

scrollLeft 和 scrollTop 都是可写的属性,将 scrollTop 设置为 0 或 Infinity 将会使元素滚动到顶部/底部。

Element.getBoundingClientRect()

Element.getBoundingClientRect() 返回元素包含border的大小,以及其相对于可视范围 (viewport) 的位置。

  • x/left:elem 左上角的 x 座标
  • y/top:elem 左上角的 y 座标
  • width:elem 的宽度,通常等于 offsetWidth
  • height:elem 的高度,通常等于 offsetHeight
  • right:elem 右下角的 x 座标
  • bottom:elem 右下角的 y 座标

这些属性有一些需要注意的事项:

座标可能是负值,例如:当元素的顶端超出视窗顶端的范围时,top就会变成负的。 IE 跟 Edge 没有 x 跟 y 属性,但可用 left 跟 top。

rect.width 跟 rect.height 可能有小数,而 offsetWidth/offsetHeight 会回传整数。如果需要精确的大小则需要用到 getBoundingClientRect()。

一般来说 rect.width 等于 elem.offsetWidth,但 elem.offsetWidth 是 layout 的大小,而 width 是实际 rendering 的大小。比如说用了 transform: scale(0.5),宽度 200px 的元素在空间上佔据的位置一样是 200px (offsetWidth),但是视觉实际看到只有 100px (rect.width)。

getComputedStyle()

获取的width和height在content-box不包含padding

还有另一种方法可以取得元素的宽高信息,那就是用getComputedStyle() 这个 API 取得元素的CSS,然后我们就可以用 getComputedStyle(elem).width 取得宽度。

但实务上并不推荐这么做,有几个原因:

  • width 会随著 box-sizing 这个属性的改变而有不同的计算方式。举例而言,同样是 width: 300px; padding: 12px;,当 box-sizing: content-box; 时,实际宽度除了内容本身的 300px ,还会外加 padding 12 * 2,一共 324px,而 box-sizing: border-box; 的时候,实际宽度就会只有 300px。

  • 同上,300px也可能会包含了捲轴的宽度,但可能我们想要的是不包含捲轴的宽度 (应用clientWidth)。

  • 值可能会是 12px 或是 auto 这类的字串

事件属性

clientX/Y

鼠标相对于浏览器窗口可视区域body的坐标(窗口坐标),可视区域不包括工具栏和滚动条。IE事件和标准事件都定义了这个属性

offsetX/Y

鼠标相对于事件源元素(srcElement)的X坐标,只有IE事件有这个属性,标准事件没有对应的属性。

pageX/Y

类似于event.clientX,但它们使用的是文档坐标而非窗口坐标。这2个属性不是标准属性,但得到了广泛支持。IE事件中没有这个属性。包括了被卷去的body部分的长度

screenX/Y

鼠标相对于用户显示器屏幕左上角的X坐标。标准事件和IE事件都定义了这个属性

window

$(window).width()/height()(jq方法)

$(window).width()获得的是屏幕可视区域的宽,不包括滚动条与工具条。

等同于document.documentElement.clientWidth

$(window).width() = document.documentElement.clientWidth = width + padding
$(window).height() = height + padding

window.innerWidth/Height

window.innerWidth获得的是可视区域的宽,但是window.innerWidth宽度包含了纵向滚动条的宽度,等同于document.documentElement.clientWidth。(IE8以及低版本浏览器不支持)。

window.innerWidth = document.documentElement.offsetWidth =width + padding + border + 纵向滚动条宽度
window.innerHeight = height + padding + border + 横向滚动条高度

window.outerWidth/outerHeight

window.outerWidthwindow.outerHeight,获得的是加上工具条与滚动条窗口的宽度与高度。

window.outerWidth = width + padding + border + 纵向滚动条宽度
window.outerHeight = height + padding + border + 横向滚动条高度 + 工具条高度 + 开发者工具

应用

当前滚动的百分比

const $html = document.documentElement
let rate = $html.scrollTop / ($html.scrollheight - $html.clientHeiht)

获取鼠标在屏幕中的百分比

let rate = e.clientX/window.outWidth

部分配图来源于网络,侵删