[new feature] IndexBar: add sticky-offset-top prop (#3791)

This commit is contained in:
neverland 2019-07-09 15:21:47 +08:00 committed by GitHub
parent 95c153dd67
commit 73cec3ac96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 3 deletions

View File

@ -65,6 +65,7 @@ export default {
| index-list | Index List | `Array` | `A-Z` | | index-list | Index List | `Array` | `A-Z` |
| z-index | z-index | `Number` | `1` | | z-index | z-index | `Number` | `1` |
| sticky | Whether to enable anchor sticky top | `Boolean` | `true` | | sticky | Whether to enable anchor sticky top | `Boolean` | `true` |
| sticky-offset-top | Anchor offset top when sticky | `Number` | `0` |
| highlight-color | Index character highlight color | `String` | `#07c160` | - | | highlight-color | Index character highlight color | `String` | `#07c160` | - |
### IndexAnchor Props ### IndexAnchor Props

View File

@ -69,6 +69,7 @@ export default {
| index-list | 索引字符列表 | `Array` | `A-Z` | - | | index-list | 索引字符列表 | `Array` | `A-Z` | - |
| z-index | z-index 层级 | `Number` | `1` | - | | z-index | z-index 层级 | `Number` | `1` | - |
| sticky | 是否开启锚点自动吸顶 | `Boolean` | `true` | - | | sticky | 是否开启锚点自动吸顶 | `Boolean` | `true` | - |
| sticky-offset-top | 锚点自动吸顶时与顶部的距离 | `Number` | `0` | 2.0.7 |
| highlight-color | 索引字符高亮颜色 | `String` | `#07c160` | - | | highlight-color | 索引字符高亮颜色 | `String` | `#07c160` | - |
### IndexAnchor Props ### IndexAnchor Props

View File

@ -3,7 +3,12 @@ import { TouchMixin } from '../mixins/touch';
import { ParentMixin } from '../mixins/relation'; import { ParentMixin } from '../mixins/relation';
import { BindEventMixin } from '../mixins/bind-event'; import { BindEventMixin } from '../mixins/bind-event';
import { GREEN } from '../utils/color'; import { GREEN } from '../utils/color';
import { getScrollTop, getElementTop, getScrollEventTarget } from '../utils/dom/scroll'; import {
getScrollTop,
getElementTop,
getRootScrollTop,
getScrollEventTarget
} from '../utils/dom/scroll';
const [createComponent, bem] = createNamespace('index-bar'); const [createComponent, bem] = createNamespace('index-bar');
@ -33,6 +38,10 @@ export default createComponent({
type: String, type: String,
default: GREEN default: GREEN
}, },
stickyOffsetTop: {
type: Number,
default: 0
},
indexList: { indexList: {
type: Array, type: Array,
default() { default() {
@ -84,7 +93,7 @@ export default createComponent({
this.children.forEach((item, index) => { this.children.forEach((item, index) => {
if (index === active) { if (index === active) {
item.active = true; item.active = true;
item.top = Math.max(0, rects[index].top - scrollTop); item.top = Math.max(this.stickyOffsetTop, rects[index].top - scrollTop);
} else if (index === active - 1) { } else if (index === active - 1) {
const activeItemTop = rects[active].top - scrollTop; const activeItemTop = rects[active].top - scrollTop;
item.active = activeItemTop > 0; item.active = activeItemTop > 0;
@ -99,7 +108,7 @@ export default createComponent({
for (let i = this.children.length - 1; i >= 0; i--) { for (let i = this.children.length - 1; i >= 0; i--) {
const prevHeight = i > 0 ? rects[i - 1].height : 0; const prevHeight = i > 0 ? rects[i - 1].height : 0;
if (scrollTop + prevHeight >= rects[i].top) { if (scrollTop + prevHeight + this.stickyOffsetTop >= rects[i].top) {
return i; return i;
} }
} }
@ -142,6 +151,11 @@ export default createComponent({
const match = this.children.filter(item => String(item.index) === index); const match = this.children.filter(item => String(item.index) === index);
if (match[0]) { if (match[0]) {
match[0].scrollIntoView(); match[0].scrollIntoView();
if (this.stickyOffsetTop) {
window.scrollTo(0, getRootScrollTop() - this.stickyOffsetTop);
}
this.$emit('select', match[0].index); this.$emit('select', match[0].index);
} }
}, },