fix(IndexBar): incorrect behavior inside popup (#7559)

This commit is contained in:
neverland 2020-11-15 10:43:12 +08:00 committed by GitHub
parent 97f2028e4e
commit d78438a899
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 32 deletions

View File

@ -1,6 +1,7 @@
import { createNamespace } from '../utils';
import { ChildrenMixin } from '../mixins/relation';
import { BORDER_BOTTOM } from '../utils/constant';
import { getScrollTop, getRootScrollTop } from '../utils/dom/scroll';
const [createComponent, bem] = createNamespace('index-anchor');
@ -15,6 +16,7 @@ export default createComponent({
return {
top: 0,
left: null,
rect: { top: 0, height: 0 },
width: null,
active: false,
};
@ -39,20 +41,35 @@ export default createComponent({
},
mounted() {
this.height = this.$el.offsetHeight;
const rect = this.$el.getBoundingClientRect();
this.rect.height = rect.height;
},
methods: {
scrollIntoView() {
this.$el.scrollIntoView();
},
getRect(scroller, scrollerRect) {
const el = this.$el;
const elRect = el.getBoundingClientRect();
this.rect.height = elRect.height;
if (scroller === window || scroller === document.body) {
this.rect.top = elRect.top + getRootScrollTop();
} else {
this.rect.top = elRect.top + getScrollTop(scroller) - scrollerRect.top;
}
return this.rect;
},
},
render() {
const { sticky } = this;
return (
<div style={{ height: sticky ? `${this.height}px` : null }}>
<div style={{ height: sticky ? `${this.rect.height}px` : null }}>
<div
style={this.anchorStyle}
class={[bem({ sticky }), { [BORDER_BOTTOM]: sticky }]}

View File

@ -5,7 +5,6 @@ import { preventDefault } from '../utils/dom/event';
import {
getScroller,
getScrollTop,
getElementTop,
getRootScrollTop,
setRootScrollTop,
} from '../utils/dom/scroll';
@ -103,10 +102,9 @@ export default createComponent({
const scrollTop = getScrollTop(this.scroller);
const scrollerRect = this.getScrollerRect();
const rects = this.children.map((item) => ({
height: item.height,
top: this.getElementTop(item.$el, scrollerRect),
}));
const rects = this.children.map((item) =>
item.getRect(this.scroller, scrollerRect)
);
const active = this.getActiveAnchorIndex(scrollTop, rects);
@ -131,7 +129,7 @@ export default createComponent({
} else if (index === active - 1) {
const activeItemTop = rects[active].top - scrollTop;
item.active = activeItemTop > 0;
item.top = activeItemTop + scrollerRect.top - item.height;
item.top = activeItemTop + scrollerRect.top - rects[index].height;
} else {
item.active = false;
}
@ -150,18 +148,6 @@ export default createComponent({
};
},
getElementTop(ele, scrollerRect) {
const { scroller } = this;
if (scroller === window || scroller === document.body) {
return getElementTop(ele);
}
const eleRect = ele.getBoundingClientRect();
return eleRect.top - scrollerRect.top + getScrollTop(scroller);
},
getActiveAnchorIndex(scrollTop, rects) {
for (let i = this.children.length - 1; i >= 0; i--) {
const prevHeight = i > 0 ? rects[i - 1].height : 0;

View File

@ -1,13 +1,5 @@
import { mount, trigger, triggerDrag, mockScrollIntoView } from '../../../test';
function mockOffsetHeight(offsetHeight) {
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
get() {
return offsetHeight;
},
});
}
test('should allow to custom anchor text', () => {
const wrapper = mount({
template: `
@ -97,11 +89,10 @@ test('should update active anchor after page scroll', () => {
const { index } = this.dataset;
return {
top: index ? index * 10 : 0,
height: 10,
};
};
mockOffsetHeight(10);
const wrapper = mount({
template: `
<van-index-bar :sticky="sticky">
@ -138,11 +129,10 @@ test('should emit change event when active index changed', () => {
const { index } = this.dataset;
return {
top: index ? index * 10 : 0,
height: 10,
};
};
mockOffsetHeight(10);
const onChange = jest.fn();
mount({