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顶部的距离的更多相关文章

  1. PyRevit开发第一步:获取Revit文档Document

    1.安装PythonShell插件 PythonShell 2018 插件下载 交流QQ群: 17075104 新建项目后,运行功能Python Shell, 在弹出的窗口中复制或输入以下引用代码模块 ...

  2. 原生js获取宽高与jquery获取宽高的方法的关系

    说明:1.因为获取高度的情况跟获取宽度的情况一样,所以以下只说获取宽度的情况.  2.以下所说的所有方法与属性所返回的值都是不带单位的.  3.为了方便说明,以下情况采用缩写表示:  obj -> ...

  3. 原生js获取鼠标坐标方法全面讲解-zmq

    原生js获取鼠标坐标方法全面讲解:clientX/Y,pageX/Y,offsetX/Y,layerX/Y,screenX/Y 一.关于js鼠标事件综合各大浏览器能获取到坐标的属性总共以下五种:eve ...

  4. 原生JS的使用,包括jquery和原生JS获取节点、jquery和原生JS修改属性的比较

    一.前言 相比于JS这条直达终点.满是荆棘的小路,jquery无疑是康庄大道了,足够的简洁.易用给了它辉煌的地位.然而,毕竟是绕着道的插件,当小路走着走着变成大路的时候,曾经的大路也就失去了他自身的优 ...

  5. 原生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 ...

  6. 原生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 ...

  7. 放弃jQuery,使用原生js吧!

    转自:http://itakeo.com/blog/2015/07/28/nojq/ 随着IE6.7.8的逐渐淘汰,HTML5的兴起,以及侧重点放在了移动端,jQuery可能变的不在那么重要,原生一样 ...

  8. 兼容各版本浏览器,封装原生Js获取ClassName

    web前端开发工作中常常会用到获取元素的className,用jQuery的$(".class")方法也可以获取className,但是有时候牵扯到数据而影响的加载顺序的原因会获取 ...

  9. 原生JS获取DOM 节点到浏览器顶部的距离或者左侧的距离

    关于js获取dom 节点到浏览器顶/左部的距离,Jquery里面有封装好的offset().top/offset().left,只到父级的顶/左部距离position().top/position() ...

随机推荐

  1. python mysql数据库压力测试

    python mysql数据库压力测试 pymysql 的执行时间对比 1,装饰器,计算插入1000条数据需要的时间 def timer(func): def decor(*args): start_ ...

  2. Oracle JDBC prefetch: how to avoid running out of RAM

    Using Oracle java JDBC (ojdbc6 11.2.0.4), loading a query with many rows takes forever (high latency ...

  3. 消息中间件 RabbitMQ 入门篇

    消息中间件 RabbitMQ 入门篇 五月君 K8S中文社区 今天   作者:五月君,来源:Nodejs技术栈 从不浪费时间的人,没有工夫抱怨时间不够.—— 杰弗逊 RabbitMQ 是一套开源(MP ...

  4. api-doc-php

    主要功能: 根据接口注释自动生成接口文档 演示地址 [Gitee Pages:]http://itxq.gitee.io/api-doc-php 开源地址: [GigHub:]https://gith ...

  5. 使用Port Forwarding连接k8s集群的pod(redis、mysql等)

    一. 创建Redis的deployment和service 1. 创建Redis deployment redis-master-deployment.yaml  apiVersion: apps/v ...

  6. android文件分享在android7.0以上版本报错的解决方案

    最近在使用蓝牙进行文件分享时,出现了一个奇怪的问题.同样的代码在android5.1上可以顺利运行,但是在android7.0上就运行失败.出现如下的错误: Caused by: android.os ...

  7. 工控随笔_25_西门子TIA 博图V14.SP1安装报错,授权错误

    前面有一篇文章说过西门子的软件安装的时候太麻烦,很容易出现错误. 但是有些错误在安装的时候却没有关系,例如下面的错误. 如上图所示,安装已经到最后一步,总结前面的修改系统组态已经打勾(✔) ,而且提示 ...

  8. PHP写接口需要注意的问题

    PHP写接口需要注意的问题方法前面建议写传过来的参数 1 防止xss攻击2 防止sql语句注入3 sign签名验证4 不经常更新的加索引和缓存 app请求时候 参数都要加urlencode 防止参数带 ...

  9. Jmeter在Http Rest接口中自动生成签名(Json格式请求参数)

    第一步: 签名的java类生成jar包,导入到jmeter的lib目录下(依赖的第三方包也要导入) 第二步:编写jmeter脚本,这里使用BeanShell 进行签名串的生成,目录结构如下: Bean ...

  10. 如何同时读取 TDateTimePicker 的 Date 和 Time ?

    由于 TDateTimePicker 只能用于日期或时间,不能同时使用.如果将Kind属性设置为dtkDate,则可以指定自定义DATE格式,但忽略任何TIME格式,并且Time未定义使用该属性.如果 ...