前言:

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

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

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

  大小:

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

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

  offsetWidth: (同理)              

  位置:

  offsetTop:元素的上外边框至包含元素的上内边框之间的像素距离。

  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高级程序设计(第三版)

js计算元素距离顶部的高度及元素是否在可视区判断的更多相关文章

  1. js获取元素的滚动高度,和距离顶部的高度

    jq: 获取浏览器显示区域(可视区域)的高度 : $(window).height(); 获取浏览器显示区域(可视区域)的宽度 : $(window).width(); 获取页面的文档高度 $(doc ...

  2. 原生js来写获取元素距离顶部距离,以及滚动条滚动指定距离和时间控制

    这是我在写vue项目里封装的一个公共js类 里面还有一些其他的方法,一并拿过来了 class Public { isDesktop(){ //判断是否为pc端 return (window.scree ...

  3. 获取一个元素距离顶部的位置和window的滚动值

    获取一个元素距离顶部的位置: $(".box").offset().top; 获取window的滚动值: $(window).scrollTop();

  4. JS获取滚动条距离顶部高度

    一.jQuery获取的相关方法 jquery 获取滚动条高度 获取浏览器显示区域的高度 : $(window).height(); 获取浏览器显示区域的宽度 : $(window).width(); ...

  5. 原生JS 和 JQ 获取滚动条的高度,以及距离顶部的高度

    JQ:相对比较简便 获取浏览器显示区域(可视区域)的高度 : $(window).height(); 获取浏览器显示区域(可视区域)的宽度 : $(window).width(); 获取页面的文档高度 ...

  6. JQ的offset().top与JS的getBoundingClientRect区别详解,JS获取元素距离视窗顶部可变距离

     壹 ❀ 引 我在 JQ的offset().top与js的offsetTop区别详解 这篇博客中详细分析了JQ方法offset().top与JS属性offsetTop的区别,并得出了一条offset( ...

  7. js获取滚动条距离浏览器顶部,底部的高度,兼容ie和firefox

    做web开发经常会碰到需要获取浏览器的滚动条与顶部和底部的距离,然后做相应的处理动作.下面作者就如何通过js来获取浏览器滚动条距离浏览器顶部和底部的高度做一下分享,这个是同时兼容ie和firefox的 ...

  8. js,jquery 获取滚动条高度和位置, 元素距顶部距离

    一,获取滚动条高度和位置 jQuery 获取览器显示区域的高度: $(window).height();  获取浏览器显示区域的宽度:$(window).width(); 获取页面的文档高度:$(do ...

  9. js获取页面元素距离浏览器工作区顶端的距离

    先介绍几个属性:(暂时只测了IE和firefox,实际上我工作中用到的最多的是chrome)  网页被卷起来的高度/宽度(即浏览器滚动条滚动后隐藏的页面内容高度) (javascript)       ...

随机推荐

  1. MySQL优化二 缓存参数优化

    数据库属于 IO密集型的应用程序,其主要职责就是数据的管理及存储工作.而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个IO是在毫秒级别,二者相差3个数量级.所以,要优化数 ...

  2. c#的unity

    1.引用对象 2.在app.config中进行配置 <?xml version="1.0" encoding="utf-8" ?> <conf ...

  3. ppt的那些小事(一)

    根据应用场景不同,幻灯片可以分为两大类,演讲型和阅读型 模板资源:(免费) OfficePLUS,微软Office官方在线模板网站!http://www.officeplus.cn/Template/ ...

  4. MySQL并发复制系列二:多线程复制 2016

    并发复制(Parallel Replication) 系列二: Enhanced Multi-threaded Slaves作者:沃趣科技MySQL数据库工程师  麻鹏飞 首先梳理下传统MySQL/M ...

  5. dulicate symbol for architecture i386 或者其他什么CPU架构 比如i386

    昨天群里有个哥们遇到和么一个问题 , 错误的大概意思呢,就是 重复定义了  一个名字. 解决办法,只能修改名字啊. 而且,错误信息 也很明确的 支出了 重复定义的类文件名字PassGuardViewC ...

  6. Python 之 基础知识(一)

    首先,对于初学者在一个项目中设置多个程序可以执行,是非常方便的,可以方便对不同知识点的练习和测试 对于商业项目而言,通常在一个项目中,只有一个可以执行的Python程序 一.注释 为了提高可读性,注释 ...

  7. ECJTUACM16 Winter vacation training #5 题解&源码

    A------------------------------------------------------------------------------------------- 题目链接:ht ...

  8. Free Pascal初次体验(有亮点哦)

    感觉上Pascal语言写的非常有条理,和英语很像,应该是比较容易学,但是写起来真的是麻烦的要死,平时一行代码用C/C++可能就是几秒钟,用Pascal就要几分钟,Free Pascal感觉也不是很好用 ...

  9. COGS 1299. bplusa【听说比a+b还要水的大水题???】

    1299. bplusa ☆   输入文件:bplusa.in   输出文件:bplusa.out   评测插件 时间限制:1 s   内存限制:128 MB [题目描述] 输入一个整数n,将其拆为两 ...

  10. exit(0)与exit(1),return三者区别(详解)

    exit(0):正常运行程序并退出程序: exit(1):非正常运行导致退出程序: return():返回函数,若在主函数中,则会退出函数并返回一值. 详细说: 1. return返回函数值,是关键字 ...