Component({ externalClasses: ['i-class'], properties : { height : { type : String, value : '300' }, itemHeight : { type : Number, value : 18 } }, relations : { '../index-item/index' : { type : 'child', linked(){ this._updateDataChange(); }, linkChanged () { this._updateDataChange(); }, unlinked () { this._updateDataChange(); } } }, data : { scrollTop : 0, fixedData : [], current : 0, timer : null, startTop : 0, itemLength : 0, currentName : '', isTouches : false }, methods : { loop(){}, _updateDataChange( ){ const indexItems = this.getRelationNodes('../index-item/index'); const len = indexItems.length; const fixedData = this.data.fixedData; /* * 使用函数节流限制重复去设置数组内容进而限制多次重复渲染 * 暂时没有研究微信在渲染的时候是否会进行函数节流 */ if (len > 0) { if( this.data.timer ){ clearTimeout( this.data.timer ) this.setData({ timer : null }) } this.data.timer = setTimeout(()=>{ const data = []; indexItems.forEach((item) => { if( item.data.name && fixedData.indexOf( item.data.name ) === -1 ){ data.push(item.data.name); item.updateDataChange(); } }) this.setData({ fixedData : data, itemLength : indexItems.length }) //组件加载完成之后重新设置顶部高度 this.setTouchStartVal(); },0); this.setData({ timer : this.data.timer }) } }, handlerScroll(event){ const detail = event.detail; const scrollTop = detail.scrollTop; const indexItems = this.getRelationNodes('../index-item/index'); indexItems.forEach((item,index)=>{ let data = item.data; let offset = data.top + data.height; if( scrollTop < offset && scrollTop >= data.top ){ this.setData({ current : index, currentName : data.currentName }) } }) }, getCurrentItem(index){ const indexItems = this.getRelationNodes('../index-item/index'); let result = {}; result = indexItems[index].data; result.total = indexItems.length; return result; }, triggerCallback(options){ this.triggerEvent('change',options) }, handlerFixedTap(event){ const eindex = event.currentTarget.dataset.index; const item = this.getCurrentItem(eindex); this.setData({ scrollTop : item.top, currentName : item.currentName, isTouches : true }) this.triggerCallback({ index : eindex, current : item.currentName }) }, handlerTouchMove(event){ const data = this.data; const touches = event.touches[0] || {}; const pageY = touches.pageY; const rest = pageY - data.startTop; let index = Math.ceil( rest/data.itemHeight ); index = index >= data.itemLength ? data.itemLength -1 : index; const movePosition = this.getCurrentItem(index); /* * 当touch选中的元素和当前currentName不相等的时候才震动一下 * 微信震动事件 */ if( movePosition.name !== this.data.currentName ){ wx.vibrateShort(); } this.setData({ scrollTop : movePosition.top, currentName : movePosition.name, isTouches : true }) this.triggerCallback({ index : index, current : movePosition.name }) }, handlerTouchEnd(){ this.setData({ isTouches : false }) }, setTouchStartVal(){ const className = '.i-index-fixed'; const query = wx.createSelectorQuery().in(this); query.select( className ).boundingClientRect((res)=>{ this.setData({ startTop : res.top }) }).exec() } } })