详解原生js实现offset方法

 更新时间:2017年06月15日 15:52:48   作者:奔跑的大兔子  
本篇文章主要介绍了原生js实现offset方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

在为 jTool 提供 offset (获取当前节点位置)方法时, 先后使用了两种方式进行实现, 现整理出来以作记录。

前后共使用了两种方式实现了该方法, 这里将这两种方法分别列出。

通过递归实现

function offset(element) {
  var offest = {
    top: 0,
    left: 0
  };

  var _position;

  getOffset(element, true);

  return offest;

  // 递归获取 offset, 可以考虑使用 getBoundingClientRect
  function getOffset(node, init) {
    // 非Element 终止递归
    if (node.nodeType !== 1) {
      return;
    }
    _position = window.getComputedStyle(node)['position'];

    // position=static: 继续递归父节点
    if (typeof(init) === 'undefined' && _position === 'static') {
      getOffset(node.parentNode);
      return;
    }
    offest.top = node.offsetTop + offest.top - node.scrollTop;
    offest.left = node.offsetLeft + offest.left - node.scrollLeft;

    // position = fixed: 获取值后退出递归
    if (_position === 'fixed') {
      return;
    }

    getOffset(node.parentNode);
  }
}

// 执行offset
var s_kw_wrap = document.querySelector('#s_kw_wrap');
offset(s_kw_wrap); // => Object {top: 181, left: 400}

通过ClientRect实现

function offset2(node) {
  var offest = {
    top: 0,
    left: 0
  };
  // 当前为IE11以下, 直接返回{top: 0, left: 0}
  if (!node.getClientRects().length) {
    return offest;
  }
  // 当前DOM节点的 display === 'node' 时, 直接返回{top: 0, left: 0}
  if (window.getComputedStyle(node)['display'] === 'none') {
    return offest;
  }
  // Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。
  // 返回值包含了一组用于描述边框的只读属性——left、top、right和bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。
  // 返回如{top: 8, right: 1432, bottom: 548, left: 8, width: 1424…}
  offest = node.getBoundingClientRect();
  var docElement = node.ownerDocument.documentElement;
  return {
    top: offest.top + window.pageYOffset - docElement.clientTop,
    left: offest.left + window.pageXOffset - docElement.clientLeft
  };
}
// 执行offset
var s_kw_wrap = document.querySelector('#s_kw_wrap');
offset2(s_kw_wrap); // => Object {top: 181.296875, left: 399.5}

offset2() 函数中使用到了 .getClientRects() 与 .getBoundingClientRect() 方法,IE11 以下浏览器并不支持; 所以该种实现, 只适于现代浏览器。

.getClientRects()

返回值是 ClientRect 对象集合(与该元素相关的CSS边框),每个 ClientRect 对象包含一组描述该边框的只读属性——left、top、right 和 bottom,单位为像素,这些属性值是相对于视口的top-left的。

并包含 length 属性, IE11以下可以通过是否包含 length 来验证当前是否为IE11以上版现。

.getBoundingClientRect()

返回值包含了一组用于描述边框的只读属性——left、top、right 和 bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。

.getBoundingClientRect() 与 .getClientRects()的关系

  1. 这两个方法的区别与当前的 display 相关, 当 display=inline 时, .getClientRects() 返回当前节点内每一行文本的 ClientRect 对象数组, 此时数组长度等于文本行数。
  2. 当 display != inline 时, .getClientRects() 返回当前节点的 ClientRect 对象数组,此时数组长度为1.
  3. .getBoundingClientRect() 总是返回当前节点的 ClientRect 对象, 注意这里是 ClientRect 对象而不是对象数组。

提示

以上测试, 可以通过在百度首页执行进行测试, document.querySelect('#s_kw_wrap') 所获取到的节点为百度首页输入框

希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • JavaScript检测原始值、引用值、属性

    JavaScript检测原始值、引用值、属性

    这篇文章主要介绍了JavaScript检测原始值、引用值、属性的相关资料,非常不错具有参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • 详解浏览器缓存和webpack缓存配置

    详解浏览器缓存和webpack缓存配置

    这篇文章主要介绍了浏览器缓存和webpack缓存配置,浏览器缓存分为两种类型,强缓存和协商缓存,具体内容详情大家参考下本文
    2018-07-07
  • JavaScript实现数组去重的14种方法大全

    JavaScript实现数组去重的14种方法大全

    亲爱的小伙伴,对于数组javascript中的数组去重方法你知道多少种呢?学会如何对数组进行去重对于javascript的学习来说也是十分重要的,下边就让我来分享一下我所知道的集中数组去重的方法吧,感兴趣的小伙伴跟着小编一起来看看吧
    2025-03-03
  • JS获取多维数组中相同键的值实现方法示例

    JS获取多维数组中相同键的值实现方法示例

    这篇文章主要介绍了JS获取多维数组中相同键的值实现方法,结合实例形式分析了JS数组遍历、判断、键值获取等操作技巧,需要的朋友可以参考下
    2017-01-01
  • 前端强大的图片预览组件Viewer.js使用方法

    前端强大的图片预览组件Viewer.js使用方法

    这篇文章主要给大家介绍了关于前端强大的图片预览组件Viewer.js使用方法的相关资料,Viewer.js是一款强大的图片查看器,虽然简单且易上手,但是却并不影响其在图片查看方面的强大功能,同时这款优秀的插件配置操作起来也非常的方便,需要的朋友可以参考下
    2024-01-01
  • js实现的页面加载完毕之前loading提示效果完整示例【附demo源码下载】

    js实现的页面加载完毕之前loading提示效果完整示例【附demo源码下载】

    这篇文章主要介绍了js实现的页面加载完毕之前loading提示效果,结合完整实例形式分析了js页面加载时显示loading效果的实现技巧,需要的朋友可以参考下
    2016-08-08
  • JS绑定事件的3种方法举例示范(简单易懂)

    JS绑定事件的3种方法举例示范(简单易懂)

    在JavaScript的学习中我们经常会遇到JavaScript的事件机制,例如事件绑定、事件监听、事件委托(事件代理)等,这篇文章主要给大家介绍了关于JS绑定事件的3种方法,需要的朋友可以参考下
    2023-11-11
  • JS实现搜索框文字可删除功能

    JS实现搜索框文字可删除功能

    本文给大家分享一段js代码实现搜索框文字可删除功能,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2016-12-12
  • 微信小程序开发之toast提示插件使用示例

    微信小程序开发之toast提示插件使用示例

    这篇文章主要给大家介绍了微信小程序开发之toast提示插件的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-06-06
  • JS集合set类的实现与使用方法示例

    JS集合set类的实现与使用方法示例

    这篇文章主要介绍了JS集合set类的实现与使用方法,结合具体实例形式分析了javascript集合的创建、元素添加、删除以及并集、交集、补集等运算相关操作技巧,需要的朋友可以参考下
    2019-02-02

最新评论