视窗与坐标

310 阅读3分钟

最近在开发一个包含一系列动画的页面,其中涉及到了每个元素在页面上或者在其父元素中的位置(坐标),所以,我觉得有必要搞懂网页上有关元素位置和页面位置的相关知识,不再为这种问题而烦恼🧐🧐

浏览器界面的组成

我们先来看浏览器的组成部分,绝大部分浏览器都是由工具栏、状态栏组成的。工具栏包括了地址栏、前进后退按钮、书签栏等浏览器自身的控件,状态栏一般在浏览器窗口的最底端,用于指示当前网页的网络请求状态。

黄框的部分称“视口(viewport) ” 是我们关注的重点,通常我们在编写网页时都不需要指定网页的高度,只需要指定网页的宽度,这是因为网页可以在竖直方向上滚动,即使网页真的很长。而视口指的就是浏览器窗口中可见的视窗部分。

元素视口大小

innerWidth & innerHeight

window.innerWidth / window.innerHeight 分别返回浏览器视口的内部宽度和内部高度,不包括控制台、浏览器工具栏的高度,如果存在滚动条,则包括滚动条的宽度或高度

outerWidth & outerHeight

window.outerWidth / window.outerHeight 分别返回浏览器窗口的宽度和高度

clientWidth & clientHeight

Element.clientWidth / Element.clientHeight分别返回元素的内部宽度和内部高度,包括内边距 padding,但不包括边框 border、外边距 margin、滚动条。

scrollHeigth & scrollWidth

Element.scrollWidth / Element.scrollHeight 属性返回元素的实际宽度和高度,包括溢出的不能显示在元素可视范围之内的部分

元素相对位置

scrollTop & scrollLeft

Element.scrollLeft 属性返回元素滚动条到元素左边的距离,Element.scrollTop 属性返回元素滚动条到元素顶部的距离。

兼容性:所有浏览器均支持

这两个属性不仅是可读的,还可以直接指定值,然后页面就会滚动到指定的位置。

offsetTop & offsetLeft

HTMLElement.offsetTop / HTMLElement.offsetLeft 为只读属性,分别返回当前元素相对于其 offsetParent 元素(直接父元素)的左上角内边距的距离。

鼠标事件坐标

screenX & screenY

event.screenX / event.screenY返回鼠标当前所处的位置相对于设备屏幕的坐标(x,y)。不会随页面滚动而改变。

兼容性:所有浏览器均支持。

pageX & pageY

event.pageX / event.pageY返回鼠标点击处相对于当前文档( 元素)的坐标,会随着页面滚动而改变。

兼容性:除I E6/7/8 不支持外,其余浏览器均支持。

clientX & clientY

event.clientX / event.clientY 返回鼠标触发点相对于浏览器视口的坐标,不随页面滚动而改变。

兼容性:所有浏览器均支持。

offsetX & offsetY

event.offsetX / event.offsetY返回鼠标点击处相对于当前鼠标事件触发的 dom 元素的坐标。不过左上角基准点在不同浏览器中有区别,IE 中以内容区左上角为基准点,不包括边框,如果触发点在边框上会返回负值;而chrome中以左上角边框处为基准点。

兼容性:IE 所有版本、chrome、Safari均完美支持,Firefox不支持。

layerX & layerY

这两个属性是 Firefox 浏览器用来替代 offsetX/Y 的,数值与offsetX/Y相同,基准点为边框左上角,如果被触发的 dom 元素具有position:relative或者position:absolute,则基准点变为 元素的边框左上角

兼容性:IE6/7/8不支持,opera不支持,IE9/10和Chrome、Safari均支持

补充

getBoundingClientRect

Element.getBoundingClientRect() 方法可以用于获取元素的大小及其相对于视口的位置(相当于 clientX/Y 的值)

<style>
  body {
    margin: 0;
  }
  
  #app {
    background-color: black;
    width: 100vw;
    height: 100vh;
  }
  
  #box {
    width: 400px;
    height: 280px;
    background-color: aquamarine;
  }
</style>

<div id="app">
  <div id="box"></div>
</div>

<script>
  const div = document.getElementById('box');
  const result = div.getBoundingClientRect();
  console.log(result);
</script>