Vue获取页面元素的相对位置的方法示例


Posted in Javascript onFebruary 05, 2020
今天在开发源码一处发现有一处需要获取元素的相对位置高度,发现getBoundingClientRect有一个问题,它是用于获取某个元素相对于视窗的位置集合,达不到我想要的要求,如是看到阮老师写的一篇文章,关于用Javascript获取页面元素的位置,很好解决了我的我问题

发现问题

当我滚动到元素的位置时候,我想把元素固定在头部

// html 结构
<div :class="['source-subnav', isFixed ? 'tab-nav-fixed' : '']" ref="subnav">
   <ul>
    <li class="active"><a href="javascript:;">首页推荐</a></li>
    <li><a href="javascript:;">最新发布</a></li>
   </ul>
</div>
export default {
  data(){
    return {
      isFixed:false,
    }
  },  
  mounted(){
    if(this.$refs.subnav.getBoundingClientRect){
    this.scrollTop(this.$refs.subnav.getBoundingClientRect())
    }
  },
  methods:{
  // 这是封装的一个方法
    scrollTop(h){
      console.log(h);
      this.utils.scrollTop((res)=>{
        this.isFixed = res.scrollH > h ? true :false;
      })
    }
  }
}

utils.js

// 该函数主要功能返回,滚动的高度以及文档占比窗口高度的百分比
utils.scrollTop = function(callback){
  // 页面总高
  var totalH = document.body.scrollHeight || document.documentElement.scrollHeight;
  // 可视高
  var clientH = window.innerHeight || document.documentElement.clientHeight;
  var result = {}
  window.addEventListener('scroll', function(e){
    // 计算有效高
    var validH = totalH - clientH
    // 滚动条卷去高度
    var scrollH = document.body.scrollTop || document.documentElement.scrollTop
    // 百分比
    result.percentage = (scrollH/validH*100).toFixed(2)
    result.scrollH = scrollH;
    callback && callback(result)
  })
}

Vue获取页面元素的相对位置的方法示例

可以看到该元素的距离顶部595px,正常显示
当我先滚动一段距离后,然后再次刷新,滚动条位置还会记录之前的位置,这是top为195px,这也是正常的,因为getBoundingClientRect是根据浏览器窗口进行定位置的
而我想要的是想要不管浏览器滚动条位置在何处时刷新浏览器,我所绑定的dom元素都是根据文档左上角进行定位的

Vue获取页面元素的相对位置的方法示例

offsetTop

网上有人说用offsetTop,其实offsetTop是对当前对象到其上级层顶部的距离。不能对其进行赋值.设置对象到页面顶部的距离请用style.top属性

获取元素距离文档顶部距离

返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合, 即:是与该元素相关的 CSS 边框集合。
DOMRect 对象包含了一组用于描述边框的只读属性: left、top、right 和 bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。
getBoundingClientRect返回值
  top: 元素上边框距离视窗顶部的距离
  bottom: 元素下边框距离视窗顶部的距离
  left: 元素左边框距离视窗左侧的距离
  right: 元素右边框距离视窗左侧的距离

由于getBoundingClientRect它们会随着视窗的滚动而相应的改变,那么元素距离页面顶部的距离就是,再加上滚动距离

this.$refs.subnav.getBoundingClientRect().top + window.scrollY; 
或者
this.$refs.subnav.getBoundingClientRect().top+document.documentElement.scrollTop;

window.scrollY不兼容ie9,如需兼容请看Window.scrollY

修改上方代码

if(this.$refs.subnav.getBoundingClientRect){
  var top1 = this.$refs.subnav.getBoundingClientRect().top + window.scrollY
  var top2 = this.$refs.subnav.getBoundingClientRect().top+document.documentElement.scrollTop;
  console.log(top1)
  console.log(top2)
  this.scrollTop(top)
}

效果如下,不管滚动条何处位置都是一个相对文档最上面的左上角

Vue获取页面元素的相对位置的方法示例

阮一峰

function getElementTop(element){

var actualTop = element.offsetTop;


var current = element.offsetParent;



while (current !== null){



actualTop += current.offsetTop;



current = current.offsetParent;


}



return actualTop;
}

实现原理

offsetTop可以返回元素距离offsetParent属性返回元素顶部的距离(如果父元素有定位的,那么将返回距离最近的定位元素,否则返回body元素,元素可能有多个定位元素,需要通过递归的方式层层获取距离,然后相加

特别说明: 需要将body的外边距设置为0,这样元素距离body顶部的距离就等同于距离文档顶部的距离

修改上方代码

if(this.$refs.subnav.getBoundingClientRect){
  var top1 = this.$refs.subnav.getBoundingClientRect().top + window.scrollY
  var top2 = this.$refs.subnav.getBoundingClientRect().top+document.documentElement.scrollTop;
  // getElementTop在上方 
  var top3 = getElementTop(this.$refs.subnav)
  console.log(top1)
  console.log(top2)
  console.log(top3)
  this.scrollTop(top)
}

效果如下

Vue获取页面元素的相对位置的方法示例

总结三种方法获取元素距离文档顶部位置

dom.getBoundingClientRect().top + window.scrollY; 
或者
dom.getBoundingClientRect().top+document.documentElement.scrollTop;
或者
function getElementTop(element){
  var actualTop = element.offsetTop;
  var current = element.offsetParent;

  while (current !== null){

 actualTop += current.offsetTop;


 current = current.offsetParent;
  }
  return actualTop;
}

参考文章

用Javascript获取页面元素的位置
获取元素距离页面顶部的距离

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript入门学习书籍推荐
Jun 12 Javascript
javascript prototype原型操作笔记
Dec 07 Javascript
简述JavaScript中正则表达式的使用方法
Jun 15 Javascript
js实现的黑背景灰色二级导航菜单效果代码
Aug 24 Javascript
AngularJs表单验证实例详解
May 30 Javascript
详解如何较好的使用js
Dec 16 Javascript
基于JS代码实现简单易用的倒计时 x 天 x 时 x 分 x 秒效果
Jul 13 Javascript
javaScript日期工具类DateUtils详解
Dec 08 Javascript
简单谈谈CommonsChunkPlugin抽取公共模块
Dec 31 Javascript
深入剖析Node.js cluster模块
May 23 Javascript
JS操作json对象key、value的常用方法分析
Oct 29 Javascript
JS新手入门数组处理的实用方法汇总
Apr 07 Javascript
vue.js使用v-model实现父子组件间的双向通信示例
Feb 05 #Javascript
vue使用原生swiper代码实例
Feb 05 #Javascript
Vue如何使用混合Mixins和插件开发详解
Feb 05 #Javascript
JS原型和原型链原理与用法实例详解
Feb 05 #Javascript
js实现视图和数据双向绑定的方法分析
Feb 05 #Javascript
小程序如何写动态标签的实现方法
Feb 05 #Javascript
vue如何实现动态加载脚本
Feb 05 #Javascript
You might like
php 方便水印和缩略图的图形类
2009/05/21 PHP
今天你说520了吗?不仅有php表白书还有java表白神器
2016/05/20 PHP
php实现有序数组打印或排序的方法【附Python、C及Go语言实现代码】
2016/11/10 PHP
javascript编程起步(第四课)
2007/01/10 Javascript
js 图片轮播(5张图片)
2008/12/30 Javascript
基于jquery自定义的漂亮单选按钮RadioButton
2013/11/19 Javascript
点击标签切换和自动切换DIV选项卡
2014/08/10 Javascript
JavaScript每天定时更换皮肤样式的方法
2015/07/01 Javascript
网页收藏夹显示ICO图标(代码少)
2015/08/04 Javascript
通过原生JS实现为元素添加事件的方法
2016/11/23 Javascript
简单谈谈Javascript函数中的arguments
2017/02/09 Javascript
ES7中利用Await减少回调嵌套的方法详解
2017/11/01 Javascript
JS使用Date对象实时显示当前系统时间简单示例
2018/08/23 Javascript
JS判断用户用的哪个浏览器实例详解
2018/10/09 Javascript
使用JS获取页面上的所有标签
2018/10/18 Javascript
vue-cli安装使用流程步骤详解
2018/11/08 Javascript
从源码里了解vue中的nextTick的使用
2018/11/22 Javascript
vue2 中二级路由高亮问题及配置方法
2019/06/10 Javascript
javascript 构建模块化开发过程解析
2019/09/11 Javascript
JS中的const命令你真懂它吗
2020/03/08 Javascript
JavaScript中使用Spread运算符的八种方法总结
2020/06/18 Javascript
一篇不错的Python入门教程
2007/02/08 Python
使用Python3中的gettext模块翻译Python源码以支持多语言
2015/03/31 Python
Python中使用PDB库调试程序
2015/04/05 Python
python关闭windows进程的方法
2015/04/18 Python
python把数组中的数字每行打印3个并保存在文档中的方法
2018/07/17 Python
Pycharm设置utf-8自动显示方法
2019/01/17 Python
python小程序基于Jupyter实现天气查询的方法
2020/03/27 Python
基于Python爬取fofa网页端数据过程解析
2020/07/13 Python
IE滤镜与CSS3效果(详细整理分享)
2013/01/25 HTML / CSS
贝玲妃美国官方网站:Benefit美国
2016/08/28 全球购物
本科毕业生专业自荐书范文
2014/02/05 职场文书
简洁的英文求职信范文
2014/05/03 职场文书
2014年超市员工工作总结
2014/11/18 职场文书
未中标通知书
2015/04/17 职场文书
React forwardRef的使用方法及注意点
2021/06/13 Javascript