直接上代码,代码内有注释。
原生js实现方法:
<body>
<div class="flex-top">
</div>
<div class="flex">
<div class="left-content">
</div>
<div class="fixed-content">
</div>
</div>
</body>
<style>
.flex-top {
height: 300px;
width: 300px;
background: red;
}
.flex {
display: flex;
}
.left-content {
width: 100px;
height: 5000px;
border: solid 1px black;
}
.fixed-content {
width: 300px;
height: 1200px;
border: solid 1px gray;
margin-left: 1px;
}
.color {
position: fixed;
bottom: 10px;
left: 110px;
}
</style>
<script>
function getElementTop(elem) {
let elemTop = elem.offsetTop;//获得elem元素距相对定位的父元素的top
elem = elem.offsetParent;//将elem换成起相对定位的父元素
while (elem != null) {
//只要还有相对定位的父元素
//获得父元素 距他父元素的top值,累加到结果中
elemTop += elem.offsetTop;
elem = elem.offsetParent;
}
return elemTop;
}
let fixedContent = document.getElementsByClassName('fixed-content')[0];
let offseTopHeight = getElementTop(fixedContent); //获取元素距离顶部高度
// fixedContent.offsetHeight //获取元素高度
// document.body.scrollTop 网页被卷去的高
// document.documentElement.clientHeight 屏幕可视高度
window.onscroll = function () {
let overHeight = document.documentElement.scrollTop;
//(元素高度 + 距离顶部高度 - 卷去高度) < 可视高度
if ((fixedContent.offsetHeight + offseTopHeight) - overHeight < document.documentElement.clientHeight) {
fixedContent.classList.add('color')
} else {
fixedContent.classList.remove('color')
}
}
</script>
Vue实现方法
//在vue内实现该功能
<div state.isFixed ? 'fixed_active' : '']" ref="fixedName">
</div>
<script>
import { onMounted } from 'vue';
const state = {
fixOffsetHeight:'', //距离顶部的高度
fixEleHeight:'', //固定元素的高度
isFixed:'' //增加class的类名
}
onMounted(() => {
window.addEventListener('scroll', handleScroll);
state.fixEleHeight = getElementTop(fixedName.value);
});
const handleScroll = () => {
let scrollTop = document.documentElement.scrollTop;
state.fixOffsetHeight = fixedName.value.offsetHeight == 0 ? state.fixOffsetHeight : fixedName.value.offsetHeight;
if ((state.fixOffsetHeight + state.fixEleHeight) - scrollTop < document.documentElement.clientHeight) {
state.isFixed = true;
} else {
state.isFixed = false;
}
};
//要记得卸载,要不然下次进入该页面会报错
onUnmounted(() => {
window.removeEventListener('scroll', handleScroll);
});
<script>