You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							243 lines
						
					
					
						
							9.3 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							243 lines
						
					
					
						
							9.3 KiB
						
					
					
				
								"use strict";
							 | 
						|
								Object.defineProperty(exports, "__esModule", { value: true });
							 | 
						|
								var color_1 = require("../common/color");
							 | 
						|
								var component_1 = require("../common/component");
							 | 
						|
								var relation_1 = require("../common/relation");
							 | 
						|
								var utils_1 = require("../common/utils");
							 | 
						|
								var page_scroll_1 = require("../mixins/page-scroll");
							 | 
						|
								var indexList = function () {
							 | 
						|
								    var indexList = [];
							 | 
						|
								    var charCodeOfA = 'A'.charCodeAt(0);
							 | 
						|
								    for (var i = 0; i < 26; i++) {
							 | 
						|
								        indexList.push(String.fromCharCode(charCodeOfA + i));
							 | 
						|
								    }
							 | 
						|
								    return indexList;
							 | 
						|
								};
							 | 
						|
								(0, component_1.VantComponent)({
							 | 
						|
								    relation: (0, relation_1.useChildren)('index-anchor', function () {
							 | 
						|
								        this.updateData();
							 | 
						|
								    }),
							 | 
						|
								    props: {
							 | 
						|
								        sticky: {
							 | 
						|
								            type: Boolean,
							 | 
						|
								            value: true,
							 | 
						|
								        },
							 | 
						|
								        zIndex: {
							 | 
						|
								            type: Number,
							 | 
						|
								            value: 1,
							 | 
						|
								        },
							 | 
						|
								        highlightColor: {
							 | 
						|
								            type: String,
							 | 
						|
								            value: color_1.GREEN,
							 | 
						|
								        },
							 | 
						|
								        stickyOffsetTop: {
							 | 
						|
								            type: Number,
							 | 
						|
								            value: 0,
							 | 
						|
								        },
							 | 
						|
								        indexList: {
							 | 
						|
								            type: Array,
							 | 
						|
								            value: indexList(),
							 | 
						|
								        },
							 | 
						|
								    },
							 | 
						|
								    mixins: [
							 | 
						|
								        (0, page_scroll_1.pageScrollMixin)(function (event) {
							 | 
						|
								            this.scrollTop = (event === null || event === void 0 ? void 0 : event.scrollTop) || 0;
							 | 
						|
								            this.onScroll();
							 | 
						|
								        }),
							 | 
						|
								    ],
							 | 
						|
								    data: {
							 | 
						|
								        activeAnchorIndex: null,
							 | 
						|
								        showSidebar: false,
							 | 
						|
								    },
							 | 
						|
								    created: function () {
							 | 
						|
								        this.scrollTop = 0;
							 | 
						|
								    },
							 | 
						|
								    methods: {
							 | 
						|
								        updateData: function () {
							 | 
						|
								            var _this = this;
							 | 
						|
								            wx.nextTick(function () {
							 | 
						|
								                if (_this.timer != null) {
							 | 
						|
								                    clearTimeout(_this.timer);
							 | 
						|
								                }
							 | 
						|
								                _this.timer = setTimeout(function () {
							 | 
						|
								                    _this.setData({
							 | 
						|
								                        showSidebar: !!_this.children.length,
							 | 
						|
								                    });
							 | 
						|
								                    _this.setRect().then(function () {
							 | 
						|
								                        _this.onScroll();
							 | 
						|
								                    });
							 | 
						|
								                }, 0);
							 | 
						|
								            });
							 | 
						|
								        },
							 | 
						|
								        setRect: function () {
							 | 
						|
								            return Promise.all([
							 | 
						|
								                this.setAnchorsRect(),
							 | 
						|
								                this.setListRect(),
							 | 
						|
								                this.setSiderbarRect(),
							 | 
						|
								            ]);
							 | 
						|
								        },
							 | 
						|
								        setAnchorsRect: function () {
							 | 
						|
								            var _this = this;
							 | 
						|
								            return Promise.all(this.children.map(function (anchor) {
							 | 
						|
								                return (0, utils_1.getRect)(anchor, '.van-index-anchor-wrapper').then(function (rect) {
							 | 
						|
								                    Object.assign(anchor, {
							 | 
						|
								                        height: rect.height,
							 | 
						|
								                        top: rect.top + _this.scrollTop,
							 | 
						|
								                    });
							 | 
						|
								                });
							 | 
						|
								            }));
							 | 
						|
								        },
							 | 
						|
								        setListRect: function () {
							 | 
						|
								            var _this = this;
							 | 
						|
								            return (0, utils_1.getRect)(this, '.van-index-bar').then(function (rect) {
							 | 
						|
								                if (!(0, utils_1.isDef)(rect)) {
							 | 
						|
								                    return;
							 | 
						|
								                }
							 | 
						|
								                Object.assign(_this, {
							 | 
						|
								                    height: rect.height,
							 | 
						|
								                    top: rect.top + _this.scrollTop,
							 | 
						|
								                });
							 | 
						|
								            });
							 | 
						|
								        },
							 | 
						|
								        setSiderbarRect: function () {
							 | 
						|
								            var _this = this;
							 | 
						|
								            return (0, utils_1.getRect)(this, '.van-index-bar__sidebar').then(function (res) {
							 | 
						|
								                if (!(0, utils_1.isDef)(res)) {
							 | 
						|
								                    return;
							 | 
						|
								                }
							 | 
						|
								                _this.sidebar = {
							 | 
						|
								                    height: res.height,
							 | 
						|
								                    top: res.top,
							 | 
						|
								                };
							 | 
						|
								            });
							 | 
						|
								        },
							 | 
						|
								        setDiffData: function (_a) {
							 | 
						|
								            var target = _a.target, data = _a.data;
							 | 
						|
								            var diffData = {};
							 | 
						|
								            Object.keys(data).forEach(function (key) {
							 | 
						|
								                if (target.data[key] !== data[key]) {
							 | 
						|
								                    diffData[key] = data[key];
							 | 
						|
								                }
							 | 
						|
								            });
							 | 
						|
								            if (Object.keys(diffData).length) {
							 | 
						|
								                target.setData(diffData);
							 | 
						|
								            }
							 | 
						|
								        },
							 | 
						|
								        getAnchorRect: function (anchor) {
							 | 
						|
								            return (0, utils_1.getRect)(anchor, '.van-index-anchor-wrapper').then(function (rect) { return ({
							 | 
						|
								                height: rect.height,
							 | 
						|
								                top: rect.top,
							 | 
						|
								            }); });
							 | 
						|
								        },
							 | 
						|
								        getActiveAnchorIndex: function () {
							 | 
						|
								            var _a = this, children = _a.children, scrollTop = _a.scrollTop;
							 | 
						|
								            var _b = this.data, sticky = _b.sticky, stickyOffsetTop = _b.stickyOffsetTop;
							 | 
						|
								            for (var i = this.children.length - 1; i >= 0; i--) {
							 | 
						|
								                var preAnchorHeight = i > 0 ? children[i - 1].height : 0;
							 | 
						|
								                var reachTop = sticky ? preAnchorHeight + stickyOffsetTop : 0;
							 | 
						|
								                if (reachTop + scrollTop >= children[i].top) {
							 | 
						|
								                    return i;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								            return -1;
							 | 
						|
								        },
							 | 
						|
								        onScroll: function () {
							 | 
						|
								            var _this = this;
							 | 
						|
								            var _a = this, _b = _a.children, children = _b === void 0 ? [] : _b, scrollTop = _a.scrollTop;
							 | 
						|
								            if (!children.length) {
							 | 
						|
								                return;
							 | 
						|
								            }
							 | 
						|
								            var _c = this.data, sticky = _c.sticky, stickyOffsetTop = _c.stickyOffsetTop, zIndex = _c.zIndex, highlightColor = _c.highlightColor;
							 | 
						|
								            var active = this.getActiveAnchorIndex();
							 | 
						|
								            this.setDiffData({
							 | 
						|
								                target: this,
							 | 
						|
								                data: {
							 | 
						|
								                    activeAnchorIndex: active,
							 | 
						|
								                },
							 | 
						|
								            });
							 | 
						|
								            if (sticky) {
							 | 
						|
								                var isActiveAnchorSticky_1 = false;
							 | 
						|
								                if (active !== -1) {
							 | 
						|
								                    isActiveAnchorSticky_1 =
							 | 
						|
								                        children[active].top <= stickyOffsetTop + scrollTop;
							 | 
						|
								                }
							 | 
						|
								                children.forEach(function (item, index) {
							 | 
						|
								                    if (index === active) {
							 | 
						|
								                        var wrapperStyle = '';
							 | 
						|
								                        var anchorStyle = "\n              color: ".concat(highlightColor, ";\n            ");
							 | 
						|
								                        if (isActiveAnchorSticky_1) {
							 | 
						|
								                            wrapperStyle = "\n                height: ".concat(children[index].height, "px;\n              ");
							 | 
						|
								                            anchorStyle = "\n                position: fixed;\n                top: ".concat(stickyOffsetTop, "px;\n                z-index: ").concat(zIndex, ";\n                color: ").concat(highlightColor, ";\n              ");
							 | 
						|
								                        }
							 | 
						|
								                        _this.setDiffData({
							 | 
						|
								                            target: item,
							 | 
						|
								                            data: {
							 | 
						|
								                                active: true,
							 | 
						|
								                                anchorStyle: anchorStyle,
							 | 
						|
								                                wrapperStyle: wrapperStyle,
							 | 
						|
								                            },
							 | 
						|
								                        });
							 | 
						|
								                    }
							 | 
						|
								                    else if (index === active - 1) {
							 | 
						|
								                        var currentAnchor = children[index];
							 | 
						|
								                        var currentOffsetTop = currentAnchor.top;
							 | 
						|
								                        var targetOffsetTop = index === children.length - 1
							 | 
						|
								                            ? _this.top
							 | 
						|
								                            : children[index + 1].top;
							 | 
						|
								                        var parentOffsetHeight = targetOffsetTop - currentOffsetTop;
							 | 
						|
								                        var translateY = parentOffsetHeight - currentAnchor.height;
							 | 
						|
								                        var anchorStyle = "\n              position: relative;\n              transform: translate3d(0, ".concat(translateY, "px, 0);\n              z-index: ").concat(zIndex, ";\n              color: ").concat(highlightColor, ";\n            ");
							 | 
						|
								                        _this.setDiffData({
							 | 
						|
								                            target: item,
							 | 
						|
								                            data: {
							 | 
						|
								                                active: true,
							 | 
						|
								                                anchorStyle: anchorStyle,
							 | 
						|
								                            },
							 | 
						|
								                        });
							 | 
						|
								                    }
							 | 
						|
								                    else {
							 | 
						|
								                        _this.setDiffData({
							 | 
						|
								                            target: item,
							 | 
						|
								                            data: {
							 | 
						|
								                                active: false,
							 | 
						|
								                                anchorStyle: '',
							 | 
						|
								                                wrapperStyle: '',
							 | 
						|
								                            },
							 | 
						|
								                        });
							 | 
						|
								                    }
							 | 
						|
								                });
							 | 
						|
								            }
							 | 
						|
								        },
							 | 
						|
								        onClick: function (event) {
							 | 
						|
								            this.scrollToAnchor(event.target.dataset.index);
							 | 
						|
								        },
							 | 
						|
								        onTouchMove: function (event) {
							 | 
						|
								            var sidebarLength = this.children.length;
							 | 
						|
								            var touch = event.touches[0];
							 | 
						|
								            var itemHeight = this.sidebar.height / sidebarLength;
							 | 
						|
								            var index = Math.floor((touch.clientY - this.sidebar.top) / itemHeight);
							 | 
						|
								            if (index < 0) {
							 | 
						|
								                index = 0;
							 | 
						|
								            }
							 | 
						|
								            else if (index > sidebarLength - 1) {
							 | 
						|
								                index = sidebarLength - 1;
							 | 
						|
								            }
							 | 
						|
								            this.scrollToAnchor(index);
							 | 
						|
								        },
							 | 
						|
								        onTouchStop: function () {
							 | 
						|
								            this.scrollToAnchorIndex = null;
							 | 
						|
								        },
							 | 
						|
								        scrollToAnchor: function (index) {
							 | 
						|
								            var _this = this;
							 | 
						|
								            if (typeof index !== 'number' || this.scrollToAnchorIndex === index) {
							 | 
						|
								                return;
							 | 
						|
								            }
							 | 
						|
								            this.scrollToAnchorIndex = index;
							 | 
						|
								            var anchor = this.children.find(function (item) { return item.data.index === _this.data.indexList[index]; });
							 | 
						|
								            if (anchor) {
							 | 
						|
								                anchor.scrollIntoView(this.scrollTop);
							 | 
						|
								                this.$emit('select', anchor.data.index);
							 | 
						|
								            }
							 | 
						|
								        },
							 | 
						|
								    },
							 | 
						|
								});
							 | 
						|
								
							 |