首页 前端知识 vue elementUi获取滚动条位置、判断是否存在滚动条、addEventListener、removeEventListener、document、window、scroll、client

vue elementUi获取滚动条位置、判断是否存在滚动条、addEventListener、removeEventListener、document、window、scroll、client

2024-02-11 10:02:48 前端知识 前端哥 468 129 我要收藏

文章目录

  • 1、vue2获取滚动条位置
  • 2、vue3获取滚动条位置
  • 3、解析
  • 4、判断是否存在滚动条


1、vue2获取滚动条位置

document方式

export default {
name: "demo",
data() {
return {
scrollTopVal: 0,
isScroll: 0
};
},
mounted() {
this.$nextTick(() => {
// 开启滚动条监听
document.addEventListener("scroll", this.scrollTop, true);
let elVal = document.getElementsByClassName('el-drawer__body')[0];
this.isScroll = elVal.scrollHeight > elVal.clientHeight;
});
},
beforeDestroy() {
document.removeEventListener('scroll', this.scrollTop, true);
},
methods: {
scrollTop() {
let elVal = document.getElementsByClassName('el-drawer__body')[0];
this.scrollTopVal = elVal.scrollTop;
}
}
};
复制

window方式

export default {
name: "demo",
data() {
return {
scrollTopVal: 0,
isScroll: 0
};
},
mounted() {
this.$nextTick(() => {
// 开启滚动条监听
window.addEventListener("scroll", this.scrollTop, true);
let elVal = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
this.isScroll = elVal.scrollHeight > elVal.clientHeight;
});
},
beforeDestroy() {
window.removeEventListener('scroll', this.scrollTop, true);
},
methods: {
scrollTop() {
let elVal = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
this.scrollTopVal = elVal.scrollTop;
},
}
};
复制

2、vue3获取滚动条位置

公共部分

import { nextTick, ref, onMounted, onBeforeUnmount } from "vue";
let scrollTopVal = ref<number>(0);
let isScroll = ref<boolean>(false);
复制

document方式

onMounted(() => {
// 监听滚动条位置
document.addEventListener("scroll", scrollTop, true);
// 设置对应元素的滚动条
let elVal: any = document.getElementsByClassName('el-drawer__body')[0];
// 判断是否存在滚动条
isScroll.value = elVal.scrollHeight > elVal.clientHeight;
});
// 实时滚动条高度
const scrollTop = () => {
nextTick(() => {
let elVal: any = document.getElementsByClassName('el-drawer__body')[0];
scrollTopVal.value = elVal.scrollTop;
});
};
onBeforeUnmount(() => {
// 参数必须和挂载时保持一致
document.removeEventListener('scroll', scrollTop, true);
});
复制

window方式

onMounted(() => {
// 监听滚动条位置
window.addEventListener('scroll', scrollTop, true);
let elVal: any = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
isScroll.value = elVal.scrollHeight > elVal.clientHeight;
});
// 实时滚动条高度
const scrollTop = () => {
nextTick(() => {
let elVal: any = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
scrollTopVal.value = elVal.scrollTop;
});
};
onBeforeUnmount(() => {
// 参数必须和挂载时保持一致
window.removeEventListener('scroll', scrollTop, true);
});
复制

3、解析

1、获取指定元素的滚动条值。在elementUi组件中需要通过class获取,因为id是动态值。
2、使用window方式时,只能检测到body或页面窗口的滚动条。然而对于elementUi的弹窗等组件获取到的滚动条值为0
3、addEventListener第三个参数表示深度监听,在某些场景如果不设置第三个参数值为true,可能监听不到对应的事件。
4、addEventListener第二个参数需要一个函数值,可以直接以函数的形式写在里面,但是不推荐这样写。
5、addEventListener第一个参数便是对应的事件名称,有滚动事件和鼠标事件等其他事件。
6、必须销毁scroll事件,因为是vue是单页面应用,如果不销毁,离开该页面后事件依然会存在,影响浏览器的性能,并且在vue3中直接报错。所以在离开此页面之前应该销毁全局监听事件,可以在组件销毁之前销毁全局监听事件。


4、判断是否存在滚动条

判断是否存在滚动条的需求,在弹窗插件中使用得较多。因为弹窗大多会添加overflow: hidden;属性,如果页面超过一屏的话,添加这个属性之后页面会有晃动。
为了增强用户体验,通过判断是否有滚动条而添加margin-left属性以抵消overflow: hidden;之后的滚动条位置。


判断竖向滚动条

console.log(el.scrollHeight > el.clientHeight);
复制

判断横向滚动条

console.log(el.scrollWidth > el.clientWidth);
复制

特殊情况

当元素指定overflow: hidden;时,不会出现滚动条。所以需要对元素是否应用了overflow: hidden;进行判断。

function hasScrolled(ele, dir = "vertical") {
// 判断的方向是否设置了overflow: hidden;
let style = window.getComputedStyle(ele);
if (
(dir == "vertical" && style.overflowY == "hidden") ||
(dir == "horizontal" && style.overflowX == "hidden")
)
return false;
// 在判断完overflow不为hidden后,再通过两个属性来判断。
if (dir == "vertical") {
return ele.scrollHeight > ele.clientHeight;
} else {
return ele.scrollWidth > ele.clientWidth;
}
}
复制

但是,以上的方法不严谨,当容器产生外边距合并的时候,也是ele.scrollWidth > ele.clientWidth


<div class="box">
<h1>子元素内部内容</h1>
</div>
复制

let box = document.querySelector(".box");
// scrollHeight: 63
console.log("scrollHeight: " + box.scrollHeight);
// clientHeight: 42
console.log("clientHeight: " + box.clientHeight);
// 是否有滚动条: true
console.log("是否有滚动条: ", box.scrollHeight > box.clientHeight);
复制

特殊情况较完美的处理方式

function hasScrolled(ele, dir = "vertical") {
let eleScroll = dir == "vertical" ? "scrollTop" : "scrollLeft";
// 判断scroll数值是否为0,还是其他值
let result = !!ele[eleScroll];
// 如果是其他数值(非0)这表示有滚动条
// 如果是0,则尝试移动一下滚动条,判断是否能够移动
if (!result) {
// 尝试移动滚动条
ele[eleScroll] = 1;
// 再次确认数值
result = !!ele[eleScroll];
// 恢复原位
ele[eleScroll] = 0;
}
// 得出结果
return result;
}
复制

计算滚动条宽度的方法

因为移动端浏览器的滚动条都是不占据页面宽度的透明样式,所以为了进一步增强用户体验,我们还需要计算滚动条的宽度,根据情况添加合理的margin-left值。
新建一个带有滚动条的div元素,再计算该元素offsetWidthclientWidth的差值。

function getScrollbarWidth() {
let scrollDiv = document.createElement("div");
scrollDiv.style.cssText = "width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;";
document.body.appendChild(scrollDiv);
let scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
document.body.removeChild(scrollDiv);
return scrollbarWidth;
}
复制
转载请注明出处或者链接地址:https://www.qianduange.cn//article/1735.html
评论
发布的文章

Jquery-day01

2024-02-25 11:02:14

Jquery的基本认识

2024-02-25 11:02:11

浏览器调用摄像头

2024-02-25 11:02:09

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!