index.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. Component({
  2. externalClasses: ['i-class'],
  3. properties : {
  4. height : {
  5. type : String,
  6. value : '300'
  7. },
  8. itemHeight : {
  9. type : Number,
  10. value : 18
  11. }
  12. },
  13. relations : {
  14. '../index-item/index' : {
  15. type : 'child',
  16. linked(){
  17. this._updateDataChange();
  18. },
  19. linkChanged () {
  20. this._updateDataChange();
  21. },
  22. unlinked () {
  23. this._updateDataChange();
  24. }
  25. }
  26. },
  27. data : {
  28. scrollTop : 0,
  29. fixedData : [],
  30. current : 0,
  31. timer : null,
  32. startTop : 0,
  33. itemLength : 0,
  34. currentName : '',
  35. isTouches : false
  36. },
  37. methods : {
  38. loop(){},
  39. _updateDataChange( ){
  40. const indexItems = this.getRelationNodes('../index-item/index');
  41. const len = indexItems.length;
  42. const fixedData = this.data.fixedData;
  43. /*
  44. * 使用函数节流限制重复去设置数组内容进而限制多次重复渲染
  45. * 暂时没有研究微信在渲染的时候是否会进行函数节流
  46. */
  47. if (len > 0) {
  48. if( this.data.timer ){
  49. clearTimeout( this.data.timer )
  50. this.setData({
  51. timer : null
  52. })
  53. }
  54. this.data.timer = setTimeout(()=>{
  55. const data = [];
  56. indexItems.forEach((item) => {
  57. if( item.data.name && fixedData.indexOf( item.data.name ) === -1 ){
  58. data.push(item.data.name);
  59. item.updateDataChange();
  60. }
  61. })
  62. this.setData({
  63. fixedData : data,
  64. itemLength : indexItems.length
  65. })
  66. //组件加载完成之后重新设置顶部高度
  67. this.setTouchStartVal();
  68. },0);
  69. this.setData({
  70. timer : this.data.timer
  71. })
  72. }
  73. },
  74. handlerScroll(event){
  75. const detail = event.detail;
  76. const scrollTop = detail.scrollTop;
  77. const indexItems = this.getRelationNodes('../index-item/index');
  78. indexItems.forEach((item,index)=>{
  79. let data = item.data;
  80. let offset = data.top + data.height;
  81. if( scrollTop < offset && scrollTop >= data.top ){
  82. this.setData({
  83. current : index,
  84. currentName : data.currentName
  85. })
  86. }
  87. })
  88. },
  89. getCurrentItem(index){
  90. const indexItems = this.getRelationNodes('../index-item/index');
  91. let result = {};
  92. result = indexItems[index].data;
  93. result.total = indexItems.length;
  94. return result;
  95. },
  96. triggerCallback(options){
  97. this.triggerEvent('change',options)
  98. },
  99. handlerFixedTap(event){
  100. const eindex = event.currentTarget.dataset.index;
  101. const item = this.getCurrentItem(eindex);
  102. this.setData({
  103. scrollTop : item.top,
  104. currentName : item.currentName,
  105. isTouches : true
  106. })
  107. this.triggerCallback({
  108. index : eindex,
  109. current : item.currentName
  110. })
  111. },
  112. handlerTouchMove(event){
  113. const data = this.data;
  114. const touches = event.touches[0] || {};
  115. const pageY = touches.pageY;
  116. const rest = pageY - data.startTop;
  117. let index = Math.ceil( rest/data.itemHeight );
  118. index = index >= data.itemLength ? data.itemLength -1 : index;
  119. const movePosition = this.getCurrentItem(index);
  120. /*
  121. * 当touch选中的元素和当前currentName不相等的时候才震动一下
  122. * 微信震动事件
  123. */
  124. if( movePosition.name !== this.data.currentName ){
  125. wx.vibrateShort();
  126. }
  127. this.setData({
  128. scrollTop : movePosition.top,
  129. currentName : movePosition.name,
  130. isTouches : true
  131. })
  132. this.triggerCallback({
  133. index : index,
  134. current : movePosition.name
  135. })
  136. },
  137. handlerTouchEnd(){
  138. this.setData({
  139. isTouches : false
  140. })
  141. },
  142. setTouchStartVal(){
  143. const className = '.i-index-fixed';
  144. const query = wx.createSelectorQuery().in(this);
  145. query.select( className ).boundingClientRect((res)=>{
  146. this.setData({
  147. startTop : res.top
  148. })
  149. }).exec()
  150. }
  151. }
  152. })