小程序组件之仿微信通讯录的实现代码


Posted in Javascript onSeptember 12, 2018

最近模仿微信通信录做了个小程序组件,分享给大家,具体如下:

效果图

小程序组件之仿微信通讯录的实现代码

因为是使用的手机录屏,视频格式为MP4,上传到文章时发现只支持图片,还好电脑自动录屏功能,所以简单的录制了一下,完后又提示只能4M,只能再去压缩图片,所以画质略渣,各位客官讲究的看看吧。

特色功能介绍

  1. 用户只需按照格式传入参数,组件能够自动将参数按首字母分组,简单方便;
  2. 组件右侧首字母导航无需另外传值,并且根据参数具体有哪些首字母显示(没有的咱就不要);
  3. 用户进行上下滑动时,左右相互联动;
  4. 点击右侧导航,组件会相应的上下滚动。

 实现基础

本组件只使用了小程序基础组件中的scroll-view,不用那么麻烦,简单方便,一看就懂,哈哈哈

wxml

滚动区域

<scroll-view scroll-y style="height:100%;white-space:nowrap;" scroll-into-view="{{toView}}" enable-back-to-top bindscroll="scroll" scroll-with-animation scroll-top="{{scrollTop}}">
 <view class="list-group" wx:for="{{logs}}" wx:for-item="group">
  <view class="title" id="{{group.title}}">{{group.title}}</view>
  <block wx:for="{{group.items}}" wx:for-item="user">
   <view id="" class="list-group-item">
    <image class="icon" src="{{user.avatar}}" lazy-load="true"></image>
    <text class="log-item">{{user.name}}</text>
   </view>
  </block>
 </view>
</scroll-view>

简单说一下上述代码:根据小程序文档,在使用**scroll-view**组件用于竖向滚动时一定要设置高度,你们可以看到我在代码中设置了'height:100%;'这就实现了组件的滚动高度是整个页面。 但是请注意:很多同学会发现设置了高度100%后,组件并没有效果,这是因为你没有将页面高度设置为100%,所以你还需在app.wxss中设置page的高度为100%; 其他的属性看文档就好,我就不再多说;

2.侧面字母导航

<view class="list-shortcut">
 <block wx:for="{{logs}}">
  <text class="{{currentIndex===index?'current':''}}" data-id="{{item.title}}" bindtap='scrollToview'>{{item.title}}</text>
 </block>
</view>

3.固定在顶部的字母导航

<view class="list-fixed {{fixedTitle=='' ? 'hide':''}}" style="transform:translate3d(0,{{fixedTop}}px,0);">
  <view class="fixed-title">
   {{fixedTitle}}
  </view>
</view>

js

渲染参数

normalizeSinger(list) {
  //列表渲染
  let map = {
   hot: {
    title: this.data.HOT_NAME,
    items: []
   }
  }
  list.forEach((item, index) => {
   if (index < this.data.HOT_SINGER_LEN) {
    map.hot.items.push({
     name: item.Fsinger_name,
     avatar:this.constructor(item.Fsinger_mid)
     })
   }
   const key = item.Findex
   if (!map[key]) {
    map[key] = {
     title: key,
     items: []
    }
   }
   map[key].items.push({
    name: item.Fsinger_name,
    avatar: this.constructor(item.Fsinger_mid)
   })
  })
  let ret = []
  let hot = []
  for (let key in map) {
   let val = map[key]
   if (val.title.match(/[a-zA-Z]/)) {
    ret.push(val)
   } else if (val.title === this.data.HOT_NAME) {
    hot.push(val)
   }
  }
  ret.sort((a, b) => {
   return a.title.charCodeAt(0) - b.title.charCodeAt(0)
  })
  return hot.concat(ret)
 },

计算分组高度

var lHeight = [],
  that = this;
let height = 0;
lHeight.push(height);
var query = wx.createSelectorQuery();
query.selectAll('.list-group').boundingClientRect(function(rects){
  var rect = rects,
    len = rect.length;
  for (let i = 0; i < len; i++) {
    height += rect[i].height;
    lHeight.push(height)
  }
 }).exec();
var calHeight = setInterval(function(){
  if (lHeight != [0]) {
    that.setData({
     listHeight: lHeight
    });
  clearInterval(calHeight);
 } 
},1000)

在获取元素属性上,小程序提供了一个很方便的api,wx.createSelectotQuery();具体使用方法请看[节点信息API][3]
使用该方法获取到各分组的高度,存入lHeight中用于之后滚动时判断使用;
同学们可以看到我在将lHeight赋值给data的listHeight时使用了定时器,这是因为获取节点信息api是异步执行的,顾你直接进行赋值是没有效果的,所以我使用了定时器功能;

**我觉得这里使用定时器不是最好的处理方式,同学们有更好的方法请告诉我,谢谢**

对滚动事件进行处理

const listHeight = this.data.listHeight
// 当滚动到顶部,scrollY<0
if (scrollY == 0 || scrollY < 0) {
 this.setData({
  currentIndex:0,
  fixedTitle:''
 })
 return
}
// 在中间部分滚动
for (let i = 0; i < listHeight.length - 1; i++) {
 let height1 = listHeight[i]
 let height2 = listHeight[i + 1]
 if (scrollY >= height1 && scrollY < height2) {
  this.setData({
   currentIndex:i,
   fixedTitle:this.data.logs[i].title
  })
  this.fixedTt(height2 - newY);
  return
 }
}
// 当滚动到底部,且-scrollY大于最后一个元素的上限
this.setData({
 currentIndex: listHeight.length - 2,
 fixedTitle: this.data.logs[listHeight.length - 2].title
})

参数格式

list:[
  {
    "index": "X",
    "name": "薛之谦",
  },
  {
    "index": "Z",
    "name": "周杰伦",
  },
  {
    "index": "B",
    "name": "BIGBANG (빅뱅)",
  },
  {
    "index": "B",
    "name": "陈奕迅",
  },
  {
    "index": "L",
    "name": "林俊杰",
  },
  {
    "index": "A",
    "name": "Alan Walker (艾伦·沃克)",
  },
]

最后

完整代码请戳 gitHub

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js 实现无干扰阴影效果 简单好用(附文件下载)
Dec 27 Javascript
js 刷新页面的代码小结 推荐
Apr 02 Javascript
js调用css属性写法
Sep 21 Javascript
jQuery简单实现上下,左右滑动的方法
Jun 01 Javascript
JS实现重新加载当前页面或者父页面的几种方法
Nov 30 Javascript
Angular4实现动态添加删除表单输入框功能
Aug 11 Javascript
vue的无缝滚动组件vue-seamless-scroll实例
Dec 18 Javascript
vue.js引入外部CSS样式和外部JS文件的方法
Jan 06 Javascript
送你43道JS面试题(收藏)
Jun 17 Javascript
js实现一款简单踩白块小游戏(曾经很火)
Dec 02 Javascript
基于Cesium绘制抛物弧线
Nov 18 Javascript
keep-alive保持组件状态的方法
Dec 02 Javascript
Vue弹出菜单功能的实现代码
Sep 12 #Javascript
angular4中*ngFor不能对返回来的对象进行循环的解决方法
Sep 12 #Javascript
详解SPA中前端路由基本原理与实现方式
Sep 12 #Javascript
对angular2中的ngfor和ngif指令嵌套实例讲解
Sep 12 #Javascript
vue-cli 使用axios的操作方法及整合axios的多种方法
Sep 12 #Javascript
Vue $emit $refs子父组件间方法的调用实例
Sep 12 #Javascript
bootstrap table表格插件之服务器端分页实例代码
Sep 12 #Javascript
You might like
php函数之子字符串替换&amp;#65279; str_replace
2011/03/23 PHP
PHP 获取远程网页内容的代码(fopen,curl已测)
2011/06/06 PHP
php数组转换js数组操作及json_encode的用法详解
2013/10/26 PHP
php显示时间常用方法小结
2015/06/05 PHP
mysql desc(DESCRIBE)命令实例讲解
2016/09/24 PHP
Hutia 的 JS 代码集
2006/10/24 Javascript
JavaScript高级程序设计 DOM学习笔记
2011/09/10 Javascript
JavaScript创建一个欢迎cookie弹出窗实现代码
2013/03/15 Javascript
javascript 弹出的窗口返回值给父窗口具体实现
2013/11/23 Javascript
用C/C++来实现 Node.js 的模块(二)
2014/09/24 Javascript
jQuery常见面试题之DOM操作详析
2017/07/05 jQuery
vue添加class样式实例讲解
2019/02/12 Javascript
JS实现的排列组合算法示例
2019/07/16 Javascript
微信分享invalid signature签名错误踩过的坑
2020/04/11 Javascript
在vue项目中 实现定义全局变量 全局函数操作
2020/10/26 Javascript
python实现在控制台输入密码不显示的方法
2015/07/02 Python
简单谈谈Python中的json与pickle
2017/07/19 Python
python 读取摄像头数据并保存的实例
2018/08/03 Python
Django继承自带user表并重写的例子
2019/11/18 Python
在echarts中图例legend和坐标系grid实现左右布局实例
2020/05/16 Python
Python代码注释规范代码实例解析
2020/08/14 Python
利用CSS3实现单选框动画特效示例代码
2016/09/26 HTML / CSS
使用Canvas操作像素的方法
2018/06/14 HTML / CSS
澳大利亚自然和有机的健康美容产品一站式商店:Ziani Beauty
2017/12/28 全球购物
英国最大的独立玩具专卖店:The Entertainer
2019/09/06 全球购物
C#里面可以避免一个类被其他类继承么?如何?
2013/09/26 面试题
大学生简历中个人的自我评价
2013/10/06 职场文书
成教毕业生自我鉴定
2013/10/23 职场文书
医学院护理专业应届生求职信
2013/11/12 职场文书
出国考察邀请函
2014/01/21 职场文书
七年级地理教学反思
2014/01/26 职场文书
个人求职信范文分享
2014/01/31 职场文书
高一军训感想
2015/08/07 职场文书
基于PostgreSQL/openGauss 的分布式数据库解决方案
2021/12/06 PostgreSQL
Spring Security使用单点登录的权限功能
2022/04/03 Java/Android
Python sklearn分类决策树方法详解
2022/09/23 Python