模仿jquery--offset方法。原生JS获取任意元素到文档document顶部的距离
1.通过遍历目标节点、目标节点的父节点,依次溯源。
然后累加这些节点到其最近可定位的祖先节点的距离。向上直到document。
其中,需要使用到节点的offsetTop/offsetLeft属性,来获取节点到最近祖先元素的距离。(position不为static)
需要使用到getComputedStyle来获取节点的计算属性。
代码实现:
function fn(ele) {
  let result = {
    left: 0,
    top: 0
  }
  // 节点display为none时,直接返回
  if (window.getComputedStyle(ele).display === 'none') return;
  function getOffset(node, init) {
    // 节点类型
    if (node.nodeType !== 1) return;
    // 定位属性值
    const position = window.getComputedStyle(node).position;
    // 目标节点跳过该判断
    if (init !== true && position === 'static') {
      getOffset(node.parentNode);
      return;
    }
    result.top += node.offsetTop - node.scrollTop;
    result.left += node.offsetLeft - node.scrollLeft;
    // 目标节点为绝对定位,无需递归操作,直接返回
    if (position === 'fixed') return;
    getOffset(node.parentNode);
    }
  getOffset(ele, true);
  return result;
}
上述代码通过递归实现,当节点类型不等于1时,返回。
当节点position为static时,不进行计算,传入父节点进行递归操作。
当目标节点隐藏时,直接返回0。
2.通过getBoundingClientRect()方法
该方法

代码实现:
function fn(ele) {
  let result = {
    top: 0,
    left: 0
  };
  if (window.getComputedStyle(ele).display === 'none') return;
  const docEl = document.documentElement;
  // 存在该方法时
  if (docEl.getBoundingClientRect) {
    result = ele.getBoundingClientRect()
    return {
      left: result.left + docEl.scrollLeft - docEl.clientLeft,
      top: result.top + docEl.scrollTop - docEl.clientTop
    }
  }
  return result;
}
其中scrollLeft/scrollTop为窗口的水平垂直的滚动距离。
clientLeft/clientTop为元素边框的宽度。
模仿jquery--offset方法。原生JS获取任意元素到文档document顶部的距离的更多相关文章
- PyRevit开发第一步:获取Revit文档Document
		1.安装PythonShell插件 PythonShell 2018 插件下载 交流QQ群: 17075104 新建项目后,运行功能Python Shell, 在弹出的窗口中复制或输入以下引用代码模块 ... 
- 原生js获取宽高与jquery获取宽高的方法的关系
		说明:1.因为获取高度的情况跟获取宽度的情况一样,所以以下只说获取宽度的情况. 2.以下所说的所有方法与属性所返回的值都是不带单位的. 3.为了方便说明,以下情况采用缩写表示: obj -> ... 
- 原生js获取鼠标坐标方法全面讲解-zmq
		原生js获取鼠标坐标方法全面讲解:clientX/Y,pageX/Y,offsetX/Y,layerX/Y,screenX/Y 一.关于js鼠标事件综合各大浏览器能获取到坐标的属性总共以下五种:eve ... 
- 原生JS的使用,包括jquery和原生JS获取节点、jquery和原生JS修改属性的比较
		一.前言 相比于JS这条直达终点.满是荆棘的小路,jquery无疑是康庄大道了,足够的简洁.易用给了它辉煌的地位.然而,毕竟是绕着道的插件,当小路走着走着变成大路的时候,曾经的大路也就失去了他自身的优 ... 
- 原生js获取鼠标坐标方法全面讲解:clientX/Y,pageX/Y,offsetX/Y,layerX/Y,screenX/Y【转】
		关于js鼠标事件综合各大浏览器能获取到坐标的属性总共以下五种 event.clientX/Y event.pageX/Y event.offsetX/Y event.layerX/Y event.sc ... 
- 原生js获取鼠标坐标方法全面讲解:clientX/Y,pageX/Y,offsetX/Y,layerX/Y,screenX/Y
		关于js鼠标事件综合各大浏览器能获取到坐标的属性总共以下五种 event.clientX/Y event.pageX/Y event.offsetX/Y event.layerX/Y event.sc ... 
- 放弃jQuery,使用原生js吧!
		转自:http://itakeo.com/blog/2015/07/28/nojq/ 随着IE6.7.8的逐渐淘汰,HTML5的兴起,以及侧重点放在了移动端,jQuery可能变的不在那么重要,原生一样 ... 
- 兼容各版本浏览器,封装原生Js获取ClassName
		web前端开发工作中常常会用到获取元素的className,用jQuery的$(".class")方法也可以获取className,但是有时候牵扯到数据而影响的加载顺序的原因会获取 ... 
- 原生JS获取DOM 节点到浏览器顶部的距离或者左侧的距离
		关于js获取dom 节点到浏览器顶/左部的距离,Jquery里面有封装好的offset().top/offset().left,只到父级的顶/左部距离position().top/position() ... 
随机推荐
- Policy Gradient Algorithms
			Policy Gradient Algorithms 2019-10-02 17:37:47 This blog is from: https://lilianweng.github.io/lil-l ... 
- zookeeper核心原理全面解析
			下述各zookeeper机制的java客户端实践参考zookeeper java客户端之curator详解. 官方文档http://zookeeper.apache.org/doc/current/z ... 
- RSA加密和数字签名在Java中常见应用【原创】
			相关术语解释: RSA,参考: https://en.wikipedia.org/wiki/RSA_(cryptosystem) 非对称加密算法 ,参考:https://baike.baidu.com ... 
- kotlin基础  尾递归
			尾调用的重要性在于它可以不在调用栈上面添加一个新的堆栈帧——而是更新它,如同迭代一般. 尾递归因而具有两个特征: 调用自身函数(Self-called): 计算仅占用常量栈空间(Stack Space ... 
- java.lang.ClassNotFoundException: com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect
			添加这个依赖 <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystr ... 
- 重温RabbitMQ
			RabbitMQ是用Erlang语言实现的,它有几个概念broker:消息队列服务器实体exchange:消息交换机,它指定消息按什么规则,路由到哪个队列queue:消息队列,每个消息都会被投入到一个 ... 
- Linux命令-nohup和&
			基础 在linux终端或控制台上执行命令时,可能不希望脚本占住屏幕需要在后台执行脚本,有几种方法让脚本在后台执行: & 当在前台运行某个作业时,终端被该作业占据:可以在命令后面加上& ... 
- maven多模块和继承
			https://blog.csdn.net/mafan121/article/details/50477852 1.maven 打包Could not resolve dependencies for ... 
- vc对话框程序运行时隐藏
			1.在资源编辑中设置对话框为不可见 2.在OnPaint中加入下面代码 void CMyDlg::OnPaint() { static b = false; if(!b){ ShowWindow(SW ... 
- Ubuntu tricks
			linux 复制文件夹内所有文件到另一个文件夹 cp -Rf /home/user1/* /root/temp/ 将 /home/user1目录下的所有东西拷到/root/temp/下而不拷贝user ... 
