微信小程序实用组件:联系人右侧拼音导航

原文:

http://www.wxapp-union.com/forum.php?mod=viewthread&tid=1328&extra=page%3D8%26filter%3Dtypeid%26typeid%3D10


wxml

<view class="flex box box-lr">
  <scroll-view class="flex groups box box-tb" scroll-y="true" scroll-into-view="{{scrollIntoView}}">
    <block wx:for="{{groups}}" wx:for-item="group">
      <view class="flex" id="{{group.groupName}}">
        <view class="group-name">{{group.groupName}}</view>
        <view class="flex group-users">
          <view wx:for="{{group.users}}" wx:for-item="user" wx:for-index="idx" class="user box box-lr">
            <view class="user-avatar box box-lr box-pack-center box-align-center">
              <image class="user-avatar-img" src="{{user.avatar}}"></image>
            </view>
            <view class="flex user-name">{{user.name}}</view>
          </view>
        </view>
      </view>
    </block>
  </scroll-view>

  <view class="nav box box-tb" bindtouchmove="touchmove" bindtouchcancel="touchcancel" bindtouchend="touchend">
    <view bindtap="tabLetter" data-index="{{item}}" wx:for="{{letters}}" class="flex box box-align-center box-pack-center letter">
      <text class="letter-text {{selected == item ? 'letter-actived' : ''}}">{{item}}</text>
    </view>
  </view>
</view>

wxss:

page {
  background-color: #eee;
}
.nav {
  position: fixed;
  right: 10rpx;
  top: 3%;
  height: 94%;
  width: 50rpx;
  font-family: Arial, Helvetica, sans-serif
}
.letter {
  width: 50rpx;
  height: 50rpx;
  font-size: 30rpx;
}
.letter-text {
  display: inline-block;
  width: 100%;
  height: 100%;
  text-align: center;
  line-height: 50rpx;
  border-radius: 50%;
}
.letter-actived {
  background-color: #ccc;
}
.groups {
  /*height: 100%;*/
}
.group-name {
  padding: 10rpx 30rpx;
  height: 50rpx;
  line-height: 50rpx;
}
.group-users {
  background-color: #fff;
}
.user {
  height: 100rpx;
  line-height: 100rpx;
  padding: 0 30rpx;
  border-bottom: 1px solid #eee;
}
.user-avatar {
  border-right: 1px solid #eee;
  width: 100rpx;
}
.user-avatar-img {
  width: 70rpx;
  height: 70rpx;
  border-radius: 50%;
}
.user-name {
  padding-left: 30rpx;
}

js

Page({
  data:{
    // 当前选择的导航字母
    selected: 0,
    // 选择字母视图滚动的位置id
    scrollIntoView: 'A',
    // 导航字母
    letters: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 
    'U', 'V', 'W', 'X', 'Y', 'Z'],
    groups: [{
        groupName: 'A',
        users: [
          {
            name: '阿码',
            avatar: '../../images/avatar.png'
          }
        ]
      },
      {
        groupName: 'B',
        users: [
          {
            name: '白娘子',
            avatar: '../../images/avatar.png'
          },
          {
            name: '包天齐',
            avatar: '../../images/avatar.png'
          }
        ]
      },
      {
        groupName: 'C',
        users: [
          {
            name: '陈大年',
            avatar: '../../images/avatar.png'
          },
          {
            name: '丛云山',
            avatar: '../../images/avatar.png'
          },
          {
            name: '崔鸣贵',
            avatar: '../../images/avatar.png'
          }
        ]
      },
      {
        groupName: 'D',
        users: [
          {
            name: '邓牛牛',
            avatar: '../../images/avatar.png'
          },
          {
            name: '刁仁衣',
            avatar: '../../images/avatar.png'
          },
          {
            name: '杜长城',
            avatar: '../../images/avatar.png'
          }
        ]
      },
      {
        groupName: 'F',
        users: [
          {
            name: '范长龙',
            avatar: '../../images/avatar.png'
          },
          {
            name: '冯肖晓',
            avatar: '../../images/avatar.png'
          }
        ]
      },
      {
        groupName: 'G',
        users: [
          {
            name: '甘地',
            avatar: '../../images/avatar.png'
          },
          {
            name: '高墙',
            avatar: '../../images/avatar.png'
          },
          {
            name: '宫都举',
            avatar: '../../images/avatar.png'
          }
        ]
      },
      {
        groupName: 'H',
        users: [
          {
            name: '何芸',
            avatar: '../../images/avatar.png'
          },
          {
            name: '胡坨坨',
            avatar: '../../images/avatar.png'
          },
          {
            name: '黄坨坨',
            avatar: '../../images/avatar.png'
          }
        ]
      },
      {
        groupName: 'T',
        users: [
          {
            name: '谭老头儿',
            avatar: '../../images/avatar.png'
          },
          {
            name: '汤云西',
            avatar: '../../images/avatar.png'
          },
          {
            name: '图图',
            avatar: '../../images/avatar.png'
          }
        ]
      },
      {
        groupName: 'X',
        users: [
          {
            name: '夏一天',
            avatar: '../../images/avatar.png'
          },
          {
            name: '鲜轰轰',
            avatar: '../../images/avatar.png'
          },
          {
            name: '谢大佩',
            avatar: '../../images/avatar.png'
          }
        ]
      }
    ]
  },
  onLoad:function(options){
    const res = wx.getSystemInfoSync(),
          letters = this.data.letters;
    // 设备信息
    this.setData({
      windowHeight: res.windowHeight,
      windowWidth: res.windowWidth,
      pixelRatio: res.pixelRatio
    });
    // 第一个字母距离顶部高度,单位使用的是rpx,须除以pixelRatio,才能与touch事件中的数值相加减,css中定义nav高度为94%,所以 *0.94
    const navHeight = this.data.windowHeight * 0.94, // 
          eachLetterHeight = navHeight / 26,
          comTop = (this.data.windowHeight - navHeight) / 2, 
          temp = [];

    this.setData({
      eachLetterHeight: eachLetterHeight
    });

    // 求各字母距离设备左上角所处位置

    for(let i = 0, len = letters.length; i < len; i++) {
      const x = this.data.windowWidth - (10 + 50) / this.data.pixelRatio,
            y = comTop + (i * eachLetterHeight);
      temp.push([x, y]);
    }
    this.setData({
      lettersPosition: temp
    })
  },
  tabLetter(e) {
    const index = e.currentTarget.dataset.index;
    this.setData({
      selected: index,
      scrollIntoView: index
    })
    
    this.cleanAcitvedStatus();
  },
  // 清除字母选中状态
  cleanAcitvedStatus() {
    setTimeout(() => {
      this.setData({
          selected: 0
      })
    }, 500);
  },
  touchmove(e) {
    const x = e.touches[0].clientX,
          y = e.touches[0].clientY,
          lettersPosition = this.data.lettersPosition,
          eachLetterHeight = this.data.eachLetterHeight,
          letters = this.data.letters;
    console.log(y);
    // 判断触摸点是否在字母导航栏上
    if(x >= lettersPosition[0][0]) {
      for(let i = 0, len = lettersPosition.length; i < len; i++) {
        // 判断落在哪个字母区域,取出对应字母所在数组的索引,根据索引更新selected及scroll-into-view的值
        const _y = lettersPosition[i][1], // 单个字母所处高度
              __y = _y + eachLetterHeight; // 单个字母最大高度取值范围, 50为字母高50rpx
        if(y >= _y && y <= __y) {
           this.setData({
            selected: letters[i],
            scrollIntoView: letters[i]
          });
          break;
        }
      }
    }
  },
  touchend(e) {
    this.cleanAcitvedStatus();
  }
})







猜你喜欢

转载自blog.csdn.net/qq_30641447/article/details/80985063