index-list.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. const throttle = function throttle(func, wait, options) {
  2. let context = void 0
  3. let args = void 0
  4. let result = void 0
  5. let timeout = null
  6. let previous = 0
  7. if (!options) options = {}
  8. const later = function later() {
  9. previous = options.leading === false ? 0 : Date.now()
  10. timeout = null
  11. result = func.apply(context, args)
  12. if (!timeout) context = args = null
  13. }
  14. return function () {
  15. const now = Date.now()
  16. if (!previous && options.leading === false) previous = now
  17. const remaining = wait - (now - previous)
  18. context = this
  19. args = arguments
  20. if (remaining <= 0 || remaining > wait) {
  21. clearTimeout(timeout)
  22. timeout = null
  23. previous = now
  24. result = func.apply(context, args)
  25. if (!timeout) context = args = null
  26. } else if (!timeout && options.trailing !== false) {
  27. timeout = setTimeout(later, remaining)
  28. }
  29. return result
  30. }
  31. }
  32. Component({
  33. behaviors: [],
  34. options: {
  35. addGlobalClass: true,
  36. pureDataPattern: /^_/
  37. },
  38. properties: {
  39. list: {
  40. type: Array,
  41. value: [],
  42. observer: function observer(newVal) {
  43. const _this = this
  44. if (newVal.length === 0) return
  45. const data = this.data
  46. const alphabet = data.list.map(function (item) {
  47. return item.alpha
  48. })
  49. this.setData({
  50. alphabet,
  51. current: alphabet[0]
  52. }, function () {
  53. _this.computedSize()
  54. })
  55. }
  56. },
  57. vibrated: {
  58. type: Boolean,
  59. value: true
  60. }
  61. },
  62. data: {
  63. windowHeight: 612,
  64. current: 'A',
  65. intoView: '',
  66. touching: false,
  67. alphabet: [],
  68. _tops: [],
  69. _anchorItemH: 0,
  70. _anchorItemW: 0,
  71. _anchorTop: 0,
  72. _listUpperBound: 0
  73. },
  74. lifetimes: {
  75. created() {
  76. },
  77. attached() {
  78. this.__scrollTo = throttle(this._scrollTo, 100, {})
  79. this.__onScroll = throttle(this._onScroll, 100, {})
  80. const _wx$getSystemInfoSync = wx.getSystemInfoSync(); const
  81. windowHeight = _wx$getSystemInfoSync.windowHeight
  82. this.setData({windowHeight})
  83. },
  84. },
  85. methods: {
  86. choose(e) {
  87. const item = e.target.dataset.item
  88. this.triggerEvent('choose', {item})
  89. },
  90. scrollTo(e) {
  91. this.__scrollTo(e)
  92. },
  93. _scrollTo(e) {
  94. const data = this.data
  95. const clientY = e.changedTouches[0].clientY
  96. const index = Math.floor((clientY - data._anchorTop) / data._anchorItemH)
  97. const current = data.alphabet[index]
  98. this.setData({current, intoView: current, touching: true})
  99. if (data.vibrated) wx.vibrateShort()
  100. },
  101. computedSize() {
  102. const data = this.data
  103. const query = this.createSelectorQuery()
  104. query.selectAll('.city_list_item').boundingClientRect(function (rects) {
  105. const result = rects
  106. data._tops = result.map(function (item) {
  107. return item.top
  108. })
  109. }).exec()
  110. query.select('.anchor-list').boundingClientRect(function (rect) {
  111. data._anchorItemH = rect.height / data.alphabet.length
  112. data._anchorItemW = rect.width
  113. data._anchorTop = rect.top
  114. }).exec()
  115. query.select('.page-select-city').boundingClientRect(function (rect) {
  116. data._listUpperBound = rect.top
  117. })
  118. },
  119. removeTouching: function removeTouching() {
  120. const _this2 = this
  121. setTimeout(function () {
  122. _this2.setData({touching: false})
  123. }, 150)
  124. },
  125. onScroll: function onScroll(e) {
  126. this.__onScroll(e)
  127. },
  128. _onScroll: function _onScroll(e) {
  129. const data = this.data
  130. const _tops = data._tops; const
  131. alphabet = data.alphabet
  132. const scrollTop = e.detail.scrollTop
  133. let current = ''
  134. if (scrollTop < _tops[0]) {
  135. current = alphabet[0]
  136. } else {
  137. for (let i = 0, len = _tops.length; i < len - 1; i++) {
  138. if (scrollTop >= _tops[i] && scrollTop < _tops[i + 1]) {
  139. current = alphabet[i]
  140. }
  141. }
  142. }
  143. if (!current) current = alphabet[alphabet.length - 1]
  144. this.setData({current})
  145. }
  146. }
  147. })