模仿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为元素边框的宽度。

posted @ 2019-11-26 16:52  chulai9527  阅读(797)  评论(0编辑  收藏  举报