js计算元素距离顶部的高度及元素是否在可视区判断

简介: 前言:  在业务当中,我们经常要计算元素的大小和元素在页面的位置信息。比如说,在一个滚动区域内,我要知道元素A是在可视区内,还是在隐藏内容区(滚动到外边看不到了)。有时还要进一步知道,元素是全部都显示在可视区,还是有部分在可视区部分在隐藏内容区。

前言:

  在业务当中,我们经常要计算元素的大小和元素在页面的位置信息。比如说,在一个滚动区域内,我要知道元素A是在可视区内,还是在隐藏内容区(滚动到外边看不到了)。有时还要进一步知道,元素是全部都显示在可视区,还是有部分在可视区部分在隐藏内容区。有时还要进一步知道,在隐藏内容区的那一部分是占多大的大小。so,来聊聊如何获取元素的大小和位置信息。

 

计算元素距离顶部的高度:偏移量

  在二维的世界里,可以想象成一个二维坐标系。每一个元素在坐标系内都有两个基本的属性:大小和位置。

  大小:

  dom元素在页面的大小有两个属性:offsetWidth 、offsetHeight,

  offsetHeight:元素在垂直方向上的占用空间大小,以像素计。包括元素的高度、(可见的)水平滚动条的高度、上边框高度和下边框高度。(我的理解:盒模型包括border内的高度总和)

  offsetWidth: (同理)               

  位置:

    offsetParent 是一个只读属性,返回一个指向最近的(closest,指包含层级上的最近)包含该元素的定位元素。如果没有定位的元素,则 offsetParent 为最近的 table, table cell 或根元素

  offsetTop:元素相对于其 offsetParent 元素的顶部的距离

  offsetLeft:(同理)

  

              

                       元素大小和位置信息图解

  原理:

  计算元素距离顶部的高度:将元素的offsetTop与其offsetParent的相同属性相加,如此循环直至根元素,就可以得到一个基本准确的值。封装如下函数(开箱即用,函数返回值即为元素距离顶部高度

 

  function getElementTop (el) {

    var actualTop = el.offsetTop

    var current = el.offsetParent

    while (current !== null) {

      actualTop += current.offsetTop

      current = current.offsetParent

    }

    return actuanlTop

  }

 

  分析一下代码:

    

  计算元素距离左部的高度:(同理可得)

 

元素是否在可视区判断:结合scrollTop

  假如这样的业务场景:有一个wrap滚动容器,wrap的内容区content的高度超过wrap的高度,则出现纵向滚动条。随意拖动滚动条到某个位置,要判断content里面的子元素input输入框是否在可视区内,若不在可视区内,自动拖动滚动条,使其进入可视区。这样的业务场景其实经常有遇到。

  原理:

  首先,根据以上getElementTop(domInput)函数,得到元素input距离顶部的高度elementTop。再结合滚动容器domWrap的scrollTop属性得到滚动条高度scrollTop(被隐藏在内容区域上方的像素数),进行比较,即可判断

  scrollTop > elementTop: 滚动条高度大于元素离顶部高度,说明元素进入了隐藏内容区,进入的量为 scrollTop -  elementTop

  scrollTop < elementTop:滚动条高度小于元素的离顶部高度,说明元素还没进入上方的隐藏内容区,如要保证元素在可视区内,则必须同时满足条件,元素不在下方的隐藏内容区: elementTop - scrollTop < document.documentElemnt.clientHeight

  结论:

  所以,元素在可视区的初步判断条件为scrollTop < elementTop && elementTop - scrollTop < document.documentElemnt.clientHeight

  以上判断还不太严谨,如果wrap还同时存在横向滚动条,还得再判断是否元素在横向的可视区内,如果要判断元素是否完全在可视区,还得加上自身的高度值,即为:scrollTop < elementTop && elementTop + input.offsetHeight - scrollTop < document.documentElemnt.clientHeight

  通过设置scrollTop属性的值domWrap.scrollTop = elementTop 可以让滚动条自动滚动,且input元素刚好在可视区的上方。

 

  ps:书上是这么说的,对于简单的CSS布局的页面,getElementTop函数可以得到非常精确的结果。对于使用表格和内嵌框架布局的页面,由于不同浏览器实现这些元素的方式不同,因此得到的结果就不太精确。在我的业务中,我没有用到表格和内嵌框架的布局,计算结果确实是精确的,可放心使用。如果使用表格和内嵌框架布局的页面,Keeping a eye on it。

 

参考文献: Javascript高级程序设计(第三版)  MDN web docs

Q&A:有疑问和指正的地方欢迎在评论区留言

 

目录
相关文章
|
12天前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
24天前
|
JavaScript 前端开发
|
24天前
|
JavaScript 前端开发 开发者
.js的dom元素操作
【10月更文挑战第29天】通过灵活运用这些 DOM 元素操作方法,JavaScript 可以实现丰富的网页交互效果,如动态更新页面内容、响应用户操作、创建和删除页面元素等。在实际开发中,开发者可以根据具体的需求和场景,选择合适的 DOM 元素操作方法来实现所需的功能,为用户提供更加流畅和动态的网页体验。
|
2月前
|
移动开发 JavaScript 前端开发
原生js如何获取dom元素的自定义属性
原生js如何获取dom元素的自定义属性
66 4
|
2月前
|
JavaScript
js删除数组中已知下标的元素
js删除数组中已知下标的元素
38 4
|
2月前
|
缓存 JavaScript 前端开发
探索Vue.js中的计算属性与侦听器
【10月更文挑战第5天】探索Vue.js中的计算属性与侦听器
24 1
|
2月前
|
JavaScript 前端开发 索引
JS 删除数组元素( 5种方法 )
JS 删除数组元素( 5种方法 )
46 1
|
3月前
|
JavaScript 前端开发
JavaScript HTML DOM 元素 (节点)
JavaScript HTML DOM 元素 (节点)
28 2
|
2月前
|
缓存 JavaScript 前端开发
深入理解Vue.js中的计算属性与侦听属性
【10月更文挑战第5天】深入理解Vue.js中的计算属性与侦听属性
29 0
|
2月前
|
缓存 JavaScript 前端开发
探索Vue.js中的计算属性与侦听器:深入理解与实践
【10月更文挑战第5天】探索Vue.js中的计算属性与侦听器:深入理解与实践
22 0