跟随
this
Make position: fixed behavior like sticky (for Vue2)
这个解决方案有点小错误(在某些情况下,它的行为很奇怪,特别是在打开其他选项卡并返回时),所以我决定使用jQuery实现它,并且它按预期工作。
下面是一个工作示例:
<template>
<div>
<div class="recap">
<div class="inner" :style="recapStyle">
</div>
</div>
</div>
</template>
<script>
export default {
name: 'ProductRecap',
data() {
return {
scrollY: null,
top: null,
bottom: null,
marginTop: 40,
recapStyle: {},
};
},
methods: {
updatePosition(scroll) {
// using jQuery to calculate amount
const offset = $(this.$el).offset().top;
const scrollAmount = offset - scroll;
const rectHeight = $(this.$el).find('.inner').outerHeight();
if (scrollAmount < this.top) {
let updatedTop = scroll - offset + this.top;
if ((scroll + rectHeight) < this.bottom) {
this.prevScroll = updatedTop;
} else {
updatedTop = this.prevScroll;
}
this.$set(this.recapStyle, 'top', `${updatedTop}px`);
} else {
this.$delete(this.recapStyle, 'top');
}
},
},
watch: {
scrollY(scrollUpdate) {
// call `updatePosition` on scroll
this.updatePosition(scrollUpdate);
},
},
mounted() {
// calculate header size (position: fixed) and add a fixed offset
this.top = $('#main-header').outerHeight() + this.marginTop;
// calculate height of the document (without the footer)
this.bottom = document.querySelector('.global-container').offsetHeight;
// update scrollY position
window.addEventListener('scroll', _.throttle(() => {
this.scrollY = Math.round(window.scrollY);
}, 20, { leading: true }));
},
};
</script>
不过,我想找到一个不使用jQuery计算偏移量的解决方案,所以我转向
You Might Not Need jQuery
,但如果我只是替换
offset
$(el).offset();
var rect = el.getBoundingClientRect();
{
top: rect.top + document.body.scrollTop,
left: rect.left + document.body.scrollLeft
}
所以我换了句台词:
const offset = $(this.$el).offset().top;
const rect = this.$el.getBoundingClientRect();
const offset = rect.top + document.body.scrollTop;
但是边栏与固定标题的距离随着滚动条的增加而增加:有人能解释一下如何修复它吗?
这是一把工作小提琴(稍微简化了一点):
Fiddle