引子

最近在尝试一个东西的时候,再次碰到需要获取元素的位置,这次还是自己来整理一下。

基本属性信息

clientHeight/clientWidth

var cHeight = element.clientHeight;
var cWidth = element.clientWidth;
  • 只读属性,是元素内容内部高度/宽度,包含内边距(padding),不包括水平/垂直滚动条、边框(border)和外边距(margin)。
  • 此属性会将获取的值四舍五入取整数。

77-client

innerHeight/innerWidth、outerHeight/outerWidth

var iHeight = window.innerHeight;
var iWidth = window.innerWidth;
  • 只读属性,浏览器窗口视口的高度。
  • 任何表现类似于窗口的任何窗口或对象(例如框架或选项卡)上都是可用的,如 window、frame、frameset 或 secondary window 。
var oHeight = window.outerHeight;
var oWidth = window.outerWidth;
  • 只读属性,整个浏览器窗口的高度,包括侧边栏、窗口镶边和窗口调正边框。

77-inner-outer

offset 相关属性

offset 一类的属性有:offsetTopoffsetLeftoffsetWidthoffsetHeight

var oLeft = element.offsetLeft;
var oTop = element.offsetTop;
var oWidth = element.offsetWidth;
var oHeight = element.offsetHeight;
  • 只读属性。
  • offsetTopoffsetLeft 相对于元素的 offsetParent 内边距边界的偏移像素值,offsetParent 是包含该元素最近的定位元素或者 table、td、th、body 元素。
  • offsetWidth/offsetHeight 包含元素的边框(border)、内边距(padding)、滚动条、以及 CSS 设置的宽度(width)/高度(height)的值。
  • 对于块级元素,以上属性描述相对于 offsetParent ;对于行内元素来说,以上属性描述相对于第一个边界框。

77-offset

scroll 相关属性

scroll 一类属性有:scrollLeftscrollTop

var sLeft = element.scrollLeft;
var sTop = element.scrollTop;

element.scrollTop = intValue
element.scrollLeft = intValue
  • 可读可写。

注意:以下所说的位置,都是指元素左上角相对于另一个元素左上角的坐标。

元素相对于父元素位置

父元素的情况可分为:直接父元素、间接父元素。

下面将问题具体化,主要使用了 offset 相关属性。复杂的布局情况可以依此类推。

对最终位置结果可能会产生影响的因素有:

  • 元素的 box-sizing 属性
  • 元素的 position 属性
  • 元素的 border 属性
  • 元素的 padding 属性

直接父元素

这是测试页面,移动端访问如下:

77-parent

间接父元素

这是测试页面,移动端访问如下:

77-higher-parent

元素是否在滚动可视区

由于不同的布局和 CSS 属性,计算方式可能会有差别,这是一个简单的示例,移动端访问如下:

77-into-view

示例主要判断逻辑

function checkIntoView() {
  var scrollEle = document.querySelector('.list');
  var scrollEleHeight = scrollEle.offsetHeight;
  var itemHeight = -document.querySelector('.item').offsetHeight;
  var intoViewEle = [];
  var scrollTopDis = scrollEle.scrollTop;
  document.querySelectorAll('.item').forEach(function(ele,index) {
    var top = ele.offsetTop;
    var gap = top - scrollTopDis;
    if (gap>itemHeight && gap <=scrollEleHeight) {
      if (intoViewEle.indexOf(index)<0) {
        var indexNum = index + 1;
        intoViewEle.push('元素 '+indexNum)
      }
    }
  })
  var showMsg = intoViewEle.join(',');
  document.querySelector('#result').innerHTML = '部分或全部已在滚动可视区的元素有:<br />'+showMsg;
}

参考资料


XXHolic
363 声望1.1k 粉丝

[链接]