fix(Sticky): shoud rerender after visibility changed (#5888)

This commit is contained in:
neverland 2020-03-23 18:35:24 +08:00 committed by GitHub
parent a11a8e8f8c
commit 7ae3a4a1b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 1 deletions

View File

@ -7,11 +7,16 @@ const [createComponent, bem] = createNamespace('sticky');
export default createComponent({
mixins: [
BindEventMixin(function(bind) {
BindEventMixin(function(bind, isBind) {
if (!this.scroller) {
this.scroller = getScroller(this.$el);
}
if (this.observer) {
const method = isBind ? 'observe' : 'unobserve';
this.observer[method](this.$el);
}
bind(this.scroller, 'scroll', this.onScroll, true);
this.onScroll();
}),
@ -58,6 +63,21 @@ export default createComponent({
},
},
created() {
// compatibility: https://caniuse.com/#feat=intersectionobserver
if (window.IntersectionObserver) {
this.observer = new IntersectionObserver(
entries => {
// trigger scroll when visibility changed
if (entries[0].intersectionRatio > 0) {
this.onScroll();
}
},
{ root: document.body }
);
}
},
methods: {
onScroll() {
if (isHidden(this.$el)) {

View File

@ -43,6 +43,22 @@ test('offset-top prop', () => {
mockScrollTop(0);
});
test('should not trigger scroll event when hidden', () => {
const scroll = jest.fn();
mount({
template: `
<van-sticky style="height: 10px; display: none;" @scroll="scroll">
Content
</van-sticky>
`,
methods: {
scroll,
},
});
expect(scroll).toHaveBeenCalledTimes(0);
});
test('container prop', () => {
const wrapper = mount({
template: `
@ -68,3 +84,52 @@ test('container prop', () => {
expect(wrapper).toMatchSnapshot();
mockScrollTop(0);
});
test('trigger scroll when visibility changed', () => {
const originIntersectionObserver = window.IntersectionObserver;
const observe = jest.fn();
const unobserve = jest.fn();
const scroll = jest.fn();
let observerCallback;
window.IntersectionObserver = class IntersectionObserver {
constructor(callback) {
observerCallback = callback;
}
observe() {
observe();
}
unobserve() {
unobserve();
}
};
const wrapper = mount({
template: `
<van-sticky style="height: 10px;" @scroll="scroll">
Content
</van-sticky>
`,
methods: {
scroll,
},
});
expect(observe).toHaveBeenCalledTimes(1);
expect(scroll).toHaveBeenCalledTimes(1);
observerCallback([{ intersectionRatio: 1 }]);
expect(scroll).toHaveBeenCalledTimes(2);
observerCallback([{ intersectionRatio: 0 }]);
expect(scroll).toHaveBeenCalledTimes(2);
wrapper.destroy();
expect(unobserve).toHaveBeenCalledTimes(1);
window.IntersectionObserver = originIntersectionObserver;
});