详解原生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来美化HTML的select标签的下拉列表效果

    用JavaScript来美化HTML的select标签的下拉列表效果

    这篇文章主要介绍了用JavaScript来美化HTML的select标签的下拉列表效果的方法,而且在多浏览器下的兼容效果也得到提升,需要的朋友可以参考下
    2015-11-11
  • bootstrap 表单验证使用方法

    bootstrap 表单验证使用方法

    在web开发过程中表单验证是比较常见的需求,友好的错误提示能够用户带来极好的用户体验效果,今天小编给大家带来如何使用bootstrap 表单验证功能,一起看看吧
    2017-01-01
  • 原生JavaScript实现简单的图形验证码

    原生JavaScript实现简单的图形验证码

    这篇文章主要为大家详细介绍了如何利用原生JavaScript实现简单的图形验证码,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以参考下
    2023-11-11
  • JQuery入门——用one()方法绑定事件处理函数(仅触发一次)

    JQuery入门——用one()方法绑定事件处理函数(仅触发一次)

    one()方法功能是为所选的元素绑定一个仅触发一次的处理函数,感兴趣的朋友可以了解下它的调用语法为:one(type, [data], fn),阅读本文或许有意外的收获呢
    2013-02-02
  • element中的$confirm的使用

    element中的$confirm的使用

    这篇文章主要介绍了element中的$confirm的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • 关于JSON与JSONP简单总结

    关于JSON与JSONP简单总结

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。而JSONP(JSON with Padding)是资料格式 JSON 的一种“使用模式”。下面是小编总结的关于JSON与JSONP知识,感兴趣的朋友一起看下吧
    2016-08-08
  • H5页面跳转小程序的3种实现方式

    H5页面跳转小程序的3种实现方式

    这篇文章主要给大家介绍了关于H5页面跳转小程序的3种实现方式,说出来你可能不信,每位商家几乎都会h5转跳到小程序、H5转跳至小程序的应用范围十分广阔,需要的朋友可以参考下
    2023-08-08
  • JS字符串拼接的几种常见方式总结

    JS字符串拼接的几种常见方式总结

    最近有经常用到连接字符串的方法,但是对整体的方法比较模糊,这里记录一下,下面这篇文章主要给大家介绍了关于JS字符串拼接的几种常见方式,需要的朋友可以参考下
    2022-11-11
  • JavaScript中Set和Map数据结构使用场景详解

    JavaScript中Set和Map数据结构使用场景详解

    这篇文章主要为大家介绍了JavaScript中Set和Map数据结构使用场景详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 微信小程序实现语音识别转文字功能及遇到的坑

    微信小程序实现语音识别转文字功能及遇到的坑

    这篇文章主要介绍了小程序实现语音识别转文字功能,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08

最新评论