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 相关文章推荐
jQuery基础框架浅入剖析
Dec 27 Javascript
jquery插件实现鼠标经过图片右侧显示大图的效果(类似淘宝)
Feb 04 Javascript
用表格输出1-1000之间的数字实现代码(附特效)
Apr 21 Javascript
SwfUpload在IE10上不出现上传按钮的解决方法
Jun 25 Javascript
node.js中的socket.io的广播消息
Dec 15 Javascript
SuperSlide标签切换、焦点图多种组合插件
Mar 14 Javascript
vue分页组件table-pagebar使用实例解析
Nov 15 Javascript
Angular ng-repeat 对象和数组遍历实例
Sep 14 Javascript
jQuery实现隔行变色的方法分析(对比原生JS)
Nov 18 Javascript
jQuery实现在新增加的元素上添加事件方法案例分析
Feb 09 Javascript
js+html获取系统当前时间
Nov 10 Javascript
Smartour 让网页导览变得更简单(推荐)
Jul 19 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
第1次亲密接触PHP5(1)
2006/10/09 PHP
php过滤危险html代码
2008/08/18 PHP
php 过滤器实现代码
2010/08/09 PHP
PHP函数篇之掌握ord()与chr()函数应用
2011/12/05 PHP
支持中文字母数字、自定义字体php验证码代码
2012/02/27 PHP
thinkPHP2.1自定义标签库的导入方法详解
2016/07/20 PHP
YII框架中使用memcache的方法详解
2017/08/02 PHP
PHP序列化和反序列化深度剖析实例讲解
2020/12/29 PHP
浅谈JavaScript中面向对象技术的模拟
2006/09/25 Javascript
javascript 实现父窗口引用弹出窗口的值的脚本
2007/08/07 Javascript
JavaScript高级程序设计 事件学习笔记
2011/09/10 Javascript
JS获取并操作iframe中元素的方法
2013/03/21 Javascript
关于在IE下的一个安全BUG --可用于跟踪用户的系统鼠标位置
2013/04/17 Javascript
js判断url是否有效的两种方法
2014/03/04 Javascript
JavaScript学习心得之概述
2015/01/20 Javascript
AngularJS指令详解及示例代码
2016/08/16 Javascript
js获取元素的标签名实现方法
2016/10/08 Javascript
微信小程序 省市区选择器实例详解(附源码下载)
2017/01/05 Javascript
Vue在页面数据渲染完成之后的调用方法
2018/09/11 Javascript
实现Vue的markdown文档可以在线运行的方法示例
2018/12/11 Javascript
vue-cli 关闭热更新操作
2020/09/18 Javascript
python实现TCP服务器端与客户端的方法详解
2015/04/30 Python
Python实现ssh批量登录并执行命令
2016/10/25 Python
python实现应用程序在右键菜单中添加打开方式功能
2017/01/09 Python
Django ImageFiled上传照片并显示的方法
2019/07/28 Python
自定义html标记替换html5新增元素
2008/10/17 HTML / CSS
马来西亚在线时尚女装商店:KEI MAG
2017/09/28 全球购物
小学生检讨书大全
2014/02/06 职场文书
网络管理专业求职信
2014/03/15 职场文书
双方协议书
2014/04/22 职场文书
过程装备与控制工程专业求职信
2014/07/02 职场文书
七一建党节慰问信
2015/02/14 职场文书
万能检讨书开头与结尾怎么写
2015/02/17 职场文书
运动会口号霸气押韵
2015/12/24 职场文书
Vue3.0中Ref与Reactive的区别示例详析
2021/07/07 Vue.js
码云(gitee)通过git自动同步到阿里云服务器
2022/12/24 Servers