mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-05 05:42:44 +08:00
fix(IndexBar): render active anchor correctly when passing sticky & stickyOffsetTop (#12837)
This commit is contained in:
parent
c6fe40867e
commit
92f373c17f
@ -140,7 +140,11 @@ export default defineComponent({
|
||||
const match = getMatchAnchor(selectActiveIndex);
|
||||
if (match) {
|
||||
const rect = match.getRect(scrollParent.value, scrollParentRect);
|
||||
active = getActiveAnchor(rect.top, rects);
|
||||
if (props.sticky && props.stickyOffsetTop) {
|
||||
active = getActiveAnchor(rect.top - props.stickyOffsetTop, rects);
|
||||
} else {
|
||||
active = getActiveAnchor(rect.top, rects);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
active = getActiveAnchor(scrollTop, rects);
|
||||
@ -229,7 +233,11 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
if (props.sticky && props.stickyOffsetTop) {
|
||||
setRootScrollTop(getRootScrollTop() - props.stickyOffsetTop);
|
||||
if (getRootScrollTop() === offsetHeight - scrollParentRect.height) {
|
||||
setRootScrollTop(getRootScrollTop());
|
||||
} else {
|
||||
setRootScrollTop(getRootScrollTop() - props.stickyOffsetTop);
|
||||
}
|
||||
}
|
||||
|
||||
emit('select', match.index);
|
||||
|
@ -6,6 +6,389 @@ exports[`should allow to custom anchor content 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`should render active anchor when stick prop is true and has stickyOffsetTop 1`] = `
|
||||
<div class="van-index-bar">
|
||||
<div class="van-index-bar__sidebar">
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="A"
|
||||
>
|
||||
A
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="B"
|
||||
>
|
||||
B
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="C"
|
||||
>
|
||||
C
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="D"
|
||||
>
|
||||
D
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="E"
|
||||
>
|
||||
E
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="F"
|
||||
>
|
||||
F
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="G"
|
||||
>
|
||||
G
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="H"
|
||||
>
|
||||
H
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="I"
|
||||
>
|
||||
I
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="J"
|
||||
>
|
||||
J
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="K"
|
||||
>
|
||||
K
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="L"
|
||||
>
|
||||
L
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="M"
|
||||
>
|
||||
M
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="N"
|
||||
>
|
||||
N
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="O"
|
||||
>
|
||||
O
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="P"
|
||||
>
|
||||
P
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="Q"
|
||||
>
|
||||
Q
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="R"
|
||||
>
|
||||
R
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="S"
|
||||
>
|
||||
S
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="T"
|
||||
>
|
||||
T
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="U"
|
||||
>
|
||||
U
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="V"
|
||||
>
|
||||
V
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="W"
|
||||
>
|
||||
W
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="X"
|
||||
>
|
||||
X
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="Y"
|
||||
>
|
||||
Y
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="Z"
|
||||
>
|
||||
Z
|
||||
</span>
|
||||
</div>
|
||||
<div data-index="0">
|
||||
<div class="van-index-anchor">
|
||||
A
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 32px;">
|
||||
A1
|
||||
</div>
|
||||
<div data-index="1">
|
||||
<div class="van-index-anchor">
|
||||
B
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 32px;">
|
||||
B1
|
||||
</div>
|
||||
<div data-index="2">
|
||||
<div class="van-index-anchor">
|
||||
C
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 32px;">
|
||||
C1
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`should render active anchor when stick prop is true and has stickyOffsetTop 2`] = `
|
||||
<div class="van-index-bar">
|
||||
<div class="van-index-bar__sidebar">
|
||||
<span
|
||||
class="van-index-bar__index van-index-bar__index--active"
|
||||
data-index="A"
|
||||
>
|
||||
A
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="B"
|
||||
>
|
||||
B
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="C"
|
||||
>
|
||||
C
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="D"
|
||||
>
|
||||
D
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="E"
|
||||
>
|
||||
E
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="F"
|
||||
>
|
||||
F
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="G"
|
||||
>
|
||||
G
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="H"
|
||||
>
|
||||
H
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="I"
|
||||
>
|
||||
I
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="J"
|
||||
>
|
||||
J
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="K"
|
||||
>
|
||||
K
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="L"
|
||||
>
|
||||
L
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="M"
|
||||
>
|
||||
M
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="N"
|
||||
>
|
||||
N
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="O"
|
||||
>
|
||||
O
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="P"
|
||||
>
|
||||
P
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="Q"
|
||||
>
|
||||
Q
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="R"
|
||||
>
|
||||
R
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="S"
|
||||
>
|
||||
S
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="T"
|
||||
>
|
||||
T
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="U"
|
||||
>
|
||||
U
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="V"
|
||||
>
|
||||
V
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="W"
|
||||
>
|
||||
W
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="X"
|
||||
>
|
||||
X
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="Y"
|
||||
>
|
||||
Y
|
||||
</span>
|
||||
<span
|
||||
class="van-index-bar__index"
|
||||
data-index="Z"
|
||||
>
|
||||
Z
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
data-index="0"
|
||||
style="height: 10px;"
|
||||
>
|
||||
<div
|
||||
class="van-index-anchor van-index-anchor--sticky van-hairline--bottom"
|
||||
style="transform: translate3d(0, 42px, 0);"
|
||||
>
|
||||
A
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 32px;">
|
||||
A1
|
||||
</div>
|
||||
<div data-index="1">
|
||||
<div class="van-index-anchor">
|
||||
B
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 32px;">
|
||||
B1
|
||||
</div>
|
||||
<div
|
||||
data-index="2"
|
||||
style
|
||||
>
|
||||
<div class="van-index-anchor">
|
||||
C
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 32px;">
|
||||
C1
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`should update active anchor after page scroll 1`] = `
|
||||
<div class="van-index-bar">
|
||||
<div class="van-index-bar__sidebar">
|
||||
|
@ -3,6 +3,7 @@ import {
|
||||
mount,
|
||||
trigger,
|
||||
triggerDrag,
|
||||
mockScrollTo,
|
||||
mockScrollTop,
|
||||
mockScrollIntoView,
|
||||
} from '../../../test';
|
||||
@ -206,3 +207,48 @@ test('should render teleport prop correctly', () => {
|
||||
|
||||
expect(root.querySelector('.van-index-bar__sidebar')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should render active anchor when stick prop is true and has stickyOffsetTop', async () => {
|
||||
const nativeRect = Element.prototype.getBoundingClientRect;
|
||||
Element.prototype.getBoundingClientRect = function () {
|
||||
const { index } = this.dataset;
|
||||
return {
|
||||
top: index ? index * (10 + 32) : 0,
|
||||
height: 10,
|
||||
};
|
||||
};
|
||||
|
||||
mockScrollTo();
|
||||
const onSelect = vi.fn();
|
||||
const onChange = vi.fn();
|
||||
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return (
|
||||
<IndexBar onSelect={onSelect} stickyOffsetTop={42} onChange={onChange}>
|
||||
<IndexAnchor index="A" data-index="0" />
|
||||
<div style={{ height: '32px' }}>A1</div>
|
||||
<IndexAnchor index="B" data-index="1" />
|
||||
<div style={{ height: '32px' }}>B1</div>
|
||||
<IndexAnchor index="C" data-index="2" />
|
||||
<div style={{ height: '32px' }}>C1</div>
|
||||
</IndexBar>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
await nextTick();
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
|
||||
const indexes = wrapper.findAll('.van-index-bar__index');
|
||||
await indexes[0].trigger('click');
|
||||
await trigger(window, 'scroll');
|
||||
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
expect(onSelect).toHaveBeenCalledWith('A');
|
||||
expect(onChange).toHaveBeenCalledWith('A');
|
||||
|
||||
wrapper.unmount();
|
||||
|
||||
Element.prototype.getBoundingClientRect = nativeRect;
|
||||
});
|
||||
|
@ -37,6 +37,14 @@ function mockHTMLElementOffset() {
|
||||
});
|
||||
}
|
||||
|
||||
export function mockScrollTo() {
|
||||
const fn = vi.fn();
|
||||
if (inBrowser) {
|
||||
window.scrollTo = fn;
|
||||
}
|
||||
return fn;
|
||||
}
|
||||
|
||||
export function mockScrollIntoView() {
|
||||
const fn = vi.fn();
|
||||
if (inBrowser) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user