前言:
position 可能失效的情况:
1、须确定设置sticky元素的参考滚动父级元素
2、指定 top, right, bottom 或 left 四个阈值其中之一(且达到设定的阈值),才可使粘性定位生效。否则其行为与相对定位相同;并且 top 和 bottom 同时设置时,top 生效的优先级高,left 和 right 同时设置时,left 的优先级高
3、如果sticky元素的参考滚动父级元素是body,设定为 position: sticky 的元素的任意父节点的 overflow 属性必须是 visible,不能是hidden/auto/scroll/overlay,否则 position:sticky 不会生效;且包裹的最近的父容器高度要大于sticky 元素的高度;如果sticky元素的参考滚动父级元素是自己设置的内部元素,参考滚动父级元素可以设置overflow :/auto/scroll/overlay,且参考滚动父级元素的高度要比内部元素小
问题现象
1:黄色板块:宽度超出可视宽度,可超出后支持左右滑动,其他板块不滑动;
2:红色板块:需要实现吸顶效果;
3:此时黄色板块css设置如下:
width: 100%;
padding: 20px 15px;
overflow-x: auto; // 与吸顶效果冲突
box-sizing: border-box;
word-break: keep-all;
4:红色板块样式如下:
padding: 10px 0;
background: rgb(211, 200, 200);
position: sticky;
top: 0;
5:position sticky失效
问题解决
思路:解决办法:新建一个克隆层,在移动下滑时候判断下滑高度生成克隆层,并在滚动栏到顶时删除克隆层;
具体实现
1:页面中基础配置
// vue中
<template>
<div class="testCopyBox" id="testCopyBox">
</div>
</div>
<div class="testBox">
<div class="testBox2">测试测试测试测试数据很长要左右滚动且吸顶数据很长要左右滚动且吸顶数据很长要左右滚动且吸顶 </div>
</div>
</template>
// css中
}
.testCopyBox {
position: fixed;
top: 40px;
left: 10;
width: 100%;
overflow: auto;
z-index: 1000;
background: #fff;
overflow-x: auto;
box-sizing: border-box;
word-break: keep-all;
.testBox2 {
padding: 30px 15px;
background: rgb(211, 200, 200);
position: sticky;
top: 0;
}
}
.testBox {
width: 100%;
padding: 20px 15px;
overflow-x: auto;
box-sizing: border-box;
word-break: keep-all;
margin-top: 50px;
.testBox2 {
padding: 30px 15px;
background: rgb(211, 200, 200);
position: sticky;
top: 0;
}
}
2:监听页面滚动
export default {
data () {
return {
topNavBg: {
backgroundColor: ''
}
}
},
// 滚动监听
mounted () {
window.addEventListener('scroll', this.handleScroll) // 监听页面滚动
},
methods: {
// 获取页面滚动距离
handleScroll () {
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
console.log(scrollTop, '滚动距离')
}
},
// 滚动重置
beforeDestroy () {
window.removeEventListener('scroll', this.handleScroll)
},
}
3:新建克隆层
methods:{
cloneDom () {
var origin = document.getElementsByClassName('testBox2')[0]
this.originNode = origin
var originNewBox = document.getElementById('testCopyBox')
// 若原本有则清空
if(originNewBox.hasChildNodes()) {
originNewBox.removeChild(originNewBox.firstChild)
}
// 否则进行克隆
originNewBox.appendChild(origin)
},
}
4:滚动删除克隆层
// 获取页面滚动距离
handleScroll () {
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
console.log(scrollTop, '滚动距离')
if (scrollTop > 60) {
// 滚动到导航栏附近则克隆元素
this.cloneDom()
} else {
// 否则删除克隆层 还原原始dom
var origin = document.getElementsByClassName('testBox2')[0]
var originNewBox = document.getElementById('testCopyBox')
if(originNewBox.hasChildNodes()) {
origin.appendChild(this.originNode)
originNewBox.removeChild(originNewBox.firstChild)
}
}
},
其他
有可能页面操作较多,此原始dom存在左右滚动现象,故而为了完全复原在吸顶后也要监听到当前吸顶dom左右滚动距离,而上述方法会重置滚动距离为0,明显不太合适;具体实现方式如下:’
实现
1:可以给当前滚动设置ref
:2:通过ref获取到原始dom scrollLeft的值
3:通过this.$refs.[‘ref名称’].scrollLeft设置为上述获取到的值