index.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. "use strict";
  2. exports.__esModule = true;
  3. exports.default = void 0;
  4. var _utils = require("../utils");
  5. var _style = require("../utils/dom/style");
  6. var _event = require("../utils/dom/event");
  7. var _scroll = require("../utils/dom/scroll");
  8. var _touch = require("../mixins/touch");
  9. var _relation = require("../mixins/relation");
  10. var _bindEvent = require("../mixins/bind-event");
  11. // Utils
  12. // Mixins
  13. function genAlphabet() {
  14. var indexList = [];
  15. var charCodeOfA = 'A'.charCodeAt(0);
  16. for (var i = 0; i < 26; i++) {
  17. indexList.push(String.fromCharCode(charCodeOfA + i));
  18. }
  19. return indexList;
  20. }
  21. var _createNamespace = (0, _utils.createNamespace)('index-bar'),
  22. createComponent = _createNamespace[0],
  23. bem = _createNamespace[1];
  24. var _default = createComponent({
  25. mixins: [_touch.TouchMixin, (0, _relation.ParentMixin)('vanIndexBar'), (0, _bindEvent.BindEventMixin)(function (bind) {
  26. if (!this.scroller) {
  27. this.scroller = (0, _scroll.getScroller)(this.$el);
  28. }
  29. bind(this.scroller, 'scroll', this.onScroll);
  30. })],
  31. props: {
  32. zIndex: [Number, String],
  33. highlightColor: String,
  34. sticky: {
  35. type: Boolean,
  36. default: true
  37. },
  38. stickyOffsetTop: {
  39. type: Number,
  40. default: 0
  41. },
  42. indexList: {
  43. type: Array,
  44. default: genAlphabet
  45. }
  46. },
  47. data: function data() {
  48. return {
  49. activeAnchorIndex: null
  50. };
  51. },
  52. computed: {
  53. sidebarStyle: function sidebarStyle() {
  54. if ((0, _utils.isDef)(this.zIndex)) {
  55. return {
  56. zIndex: this.zIndex + 1
  57. };
  58. }
  59. },
  60. highlightStyle: function highlightStyle() {
  61. var highlightColor = this.highlightColor;
  62. if (highlightColor) {
  63. return {
  64. color: highlightColor
  65. };
  66. }
  67. }
  68. },
  69. watch: {
  70. indexList: function indexList() {
  71. this.$nextTick(this.onScroll);
  72. },
  73. activeAnchorIndex: function activeAnchorIndex(value) {
  74. if (value) {
  75. this.$emit('change', value);
  76. }
  77. }
  78. },
  79. methods: {
  80. onScroll: function onScroll() {
  81. var _this = this;
  82. if ((0, _style.isHidden)(this.$el)) {
  83. return;
  84. }
  85. var scrollTop = (0, _scroll.getScrollTop)(this.scroller);
  86. var scrollerRect = this.getScrollerRect();
  87. var rects = this.children.map(function (item) {
  88. return item.getRect(_this.scroller, scrollerRect);
  89. });
  90. var active = this.getActiveAnchorIndex(scrollTop, rects);
  91. this.activeAnchorIndex = this.indexList[active];
  92. if (this.sticky) {
  93. this.children.forEach(function (item, index) {
  94. if (index === active || index === active - 1) {
  95. var rect = item.$el.getBoundingClientRect();
  96. item.left = rect.left;
  97. item.width = rect.width;
  98. } else {
  99. item.left = null;
  100. item.width = null;
  101. }
  102. if (index === active) {
  103. item.active = true;
  104. item.top = Math.max(_this.stickyOffsetTop, rects[index].top - scrollTop) + scrollerRect.top;
  105. } else if (index === active - 1) {
  106. var activeItemTop = rects[active].top - scrollTop;
  107. item.active = activeItemTop > 0;
  108. item.top = activeItemTop + scrollerRect.top - rects[index].height;
  109. } else {
  110. item.active = false;
  111. }
  112. });
  113. }
  114. },
  115. getScrollerRect: function getScrollerRect() {
  116. if (this.scroller.getBoundingClientRect) {
  117. return this.scroller.getBoundingClientRect();
  118. }
  119. return {
  120. top: 0,
  121. left: 0
  122. };
  123. },
  124. getActiveAnchorIndex: function getActiveAnchorIndex(scrollTop, rects) {
  125. for (var i = this.children.length - 1; i >= 0; i--) {
  126. var prevHeight = i > 0 ? rects[i - 1].height : 0;
  127. var reachTop = this.sticky ? prevHeight + this.stickyOffsetTop : 0;
  128. if (scrollTop + reachTop >= rects[i].top) {
  129. return i;
  130. }
  131. }
  132. return -1;
  133. },
  134. onClick: function onClick(event) {
  135. this.scrollToElement(event.target);
  136. },
  137. onTouchMove: function onTouchMove(event) {
  138. this.touchMove(event);
  139. if (this.direction === 'vertical') {
  140. (0, _event.preventDefault)(event);
  141. var _event$touches$ = event.touches[0],
  142. clientX = _event$touches$.clientX,
  143. clientY = _event$touches$.clientY;
  144. var target = document.elementFromPoint(clientX, clientY);
  145. if (target) {
  146. var index = target.dataset.index;
  147. /* istanbul ignore else */
  148. if (this.touchActiveIndex !== index) {
  149. this.touchActiveIndex = index;
  150. this.scrollToElement(target);
  151. }
  152. }
  153. }
  154. },
  155. scrollTo: function scrollTo(index) {
  156. var match = this.children.filter(function (item) {
  157. return String(item.index) === index;
  158. });
  159. if (match[0]) {
  160. match[0].scrollIntoView();
  161. if (this.sticky && this.stickyOffsetTop) {
  162. (0, _scroll.setRootScrollTop)((0, _scroll.getRootScrollTop)() - this.stickyOffsetTop);
  163. }
  164. this.$emit('select', match[0].index);
  165. }
  166. },
  167. scrollToElement: function scrollToElement(element) {
  168. var index = element.dataset.index;
  169. this.scrollTo(index);
  170. },
  171. onTouchEnd: function onTouchEnd() {
  172. this.active = null;
  173. }
  174. },
  175. render: function render() {
  176. var _this2 = this;
  177. var h = arguments[0];
  178. var Indexes = this.indexList.map(function (index) {
  179. var active = index === _this2.activeAnchorIndex;
  180. return h("span", {
  181. "class": bem('index', {
  182. active: active
  183. }),
  184. "style": active ? _this2.highlightStyle : null,
  185. "attrs": {
  186. "data-index": index
  187. }
  188. }, [index]);
  189. });
  190. return h("div", {
  191. "class": bem()
  192. }, [h("div", {
  193. "class": bem('sidebar'),
  194. "style": this.sidebarStyle,
  195. "on": {
  196. "click": this.onClick,
  197. "touchstart": this.touchStart,
  198. "touchmove": this.onTouchMove,
  199. "touchend": this.onTouchEnd,
  200. "touchcancel": this.onTouchEnd
  201. }
  202. }, [Indexes]), this.slots('default')]);
  203. }
  204. });
  205. exports.default = _default;