diff --git a/src/index-bar/index.js b/src/index-bar/index.js index b6954f830..38977318c 100644 --- a/src/index-bar/index.js +++ b/src/index-bar/index.js @@ -17,7 +17,7 @@ export default createComponent({ mixins: [ TouchMixin, ParentMixin('vanIndexBar'), - BindEventMixin(function(bind) { + BindEventMixin(function (bind) { if (!this.scroller) { this.scroller = getScrollEventTarget(this.$el); } @@ -84,16 +84,11 @@ export default createComponent({ methods: { onScroll() { - let scrollTop; - if (this.scroller === window || this.scroller === document.body) { - scrollTop = getScrollTop(this.scroller); - } else { - // see: https://github.com/youzan/vant/issues/3774 - scrollTop = 0; - } + const scrollTop = getScrollTop(this.scroller); + const scrollerRect = this.getScrollerRect(); const rects = this.children.map(item => ({ height: item.height, - top: getElementTop(item.$el) + top: this.getElementTop(item.$el, scrollerRect) })); const active = this.getActiveAnchorIndex(scrollTop, rects); @@ -104,11 +99,11 @@ export default createComponent({ this.children.forEach((item, index) => { if (index === active) { item.active = true; - item.top = Math.max(this.stickyOffsetTop, rects[index].top - scrollTop); + item.top = Math.max(this.stickyOffsetTop, rects[index].top - scrollTop) + scrollerRect.top; } else if (index === active - 1) { const activeItemTop = rects[active].top - scrollTop; item.active = activeItemTop > 0; - item.top = activeItemTop - item.height; + item.top = activeItemTop + scrollerRect.top - item.height; } else { item.active = false; } @@ -116,6 +111,32 @@ export default createComponent({ } }, + getScrollerRect() { + const { scroller } = this; + let scrollerRect = { + top: 0, + left: 0, + }; + + if (scroller.getBoundingClientRect) { + scrollerRect = scroller.getBoundingClientRect(); + } + + return scrollerRect; + }, + + 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; @@ -196,7 +217,7 @@ export default createComponent({
-
ABCDEFGHIJKLMNOPQRSTUVWXYZ
+
ABCDEFGHIJKLMNOPQRSTUVWXYZ
A
diff --git a/src/index-bar/test/__snapshots__/index.spec.js.snap b/src/index-bar/test/__snapshots__/index.spec.js.snap index bef60e616..f8d487743 100644 --- a/src/index-bar/test/__snapshots__/index.spec.js.snap +++ b/src/index-bar/test/__snapshots__/index.spec.js.snap @@ -2,7 +2,7 @@ exports[`custom anchor text 1`] = `
-
ABCDEFGHIJKLMNOPQRSTUVWXYZ
+
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Title A
@@ -14,7 +14,7 @@ exports[`custom anchor text 1`] = ` exports[`scroll and update active anchor 1`] = `
-
ABCDEFGHIJKLMNOPQRSTUVWXYZ
+
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1
@@ -32,7 +32,7 @@ exports[`scroll and update active anchor 1`] = ` exports[`scroll and update active anchor 2`] = `
-
ABCDEFGHIJKLMNOPQRSTUVWXYZ
+
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1