微信小程序自定义滚动选择器

本文实例为大家分享了微信小程序自定义滚动选择器的具体代码,供大家参考,具体内容如下

最近项目里有个需求要做个滚动选择器,在网上找了半天也没找到合适的demo,没办法只能发挥我的聪明才智创造一个,上代码。

js:

// pages/xuanzeqi/xuanzeqi.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    list: ['0分', '1分', '2分', '3分', '4分', '5分', '6分', '7分', '8分', '9分', '10分', '11分', '12分', '13分', '14分', '15分', '16分', '17分', '18分', '19分', '20分', '21分', '22分', '23分', '24分', '25分', '26分', '27分', '28分', '29分', '30分', '31分', '32分', '33分', '34分', '35分', '36分', '37分', '38分', '39分', '40分', '41分', '42分', '43分', '44分', '45分', '46分', '47分', '48分', '49分', '50分', '51分', '52分', '53分', '54分', '55分', '56分', '57分', '58分', '59分'],
    box_height: 0,//选择器的高度(非控制项,自动计算),单位px
    picker:{ //选择器的控制变量
      box_width: 200,//选择器宽度,单位px
      choose_item_height: 30,//选择器中每一项选项的高度,单位px
      choose_item_font_size:25,//选择器中每一项选项字体大小,单位px
      scroll_animation: true,//是否使用动画过渡
      choose_item_number: 13,//选择器内选项的个数(要求为单数)
      bgColor:'#01356f',//选择器的背景颜色
      choose_item_font_color:'white',//选择器选项的字体颜色
    },
    mid_item:0,
    scroll_into_view:'item_0',//滚动到选项的id
    item_height_list:[],//存储每一项距离顶端的y轴数据
    picker_value:null,//选择器的值
    opacity_list:[],//透明阶梯
    cover_list: [],//遮盖层属性列表
    touchY: -1,
    scrollTop:0,
  },
  touchMove: function (e) {
    let that = this
    let touY = e.touches[0].pageY;
    if(that.data.touchY == -1){
      that.data.touchY = touY
    } else{
      let cha = that.data.touchY - touY
      that.setData({
        scrollTop: that.data.scrollTop + cha
      })
      that.data.touchY = touY
    }
    if (that.coverEndTimer) {
      clearTimeout(that.coverEndTimer);
      that.coverEndTimer = null;
    }
    that.coverEndTimer = setTimeout(function () {
      that.data.touchY = -1
    }, 200);
  },
  //监听选择器滚动事件
  bindscrollevent:function(e){
    let that = this
    // that.flashOpacity(e.detail.scrollTop)
    console.log(e)
    if (that.scrollEndTimer) {
      clearTimeout(that.scrollEndTimer);
      that.scrollEndTimer = null;
    }
    that.scrollEndTimer = setTimeout(function () {
      console.log("滑动结束");
      // that.flashOpacity(e.detail.scrollTop)
      that.itemToMid(e.detail.scrollTop)
      that.data.scrollTop = e.detail.scrollTop
    }, 200);
  },
  //更新透明度
  flashOpacity:function(e){
    let that = this
    
    that.setData({
      item_height_list: that.data.item_height_list
    })
    for (let i in that.data.item_height_list) {
      if (that.data.item_height_list[i].bottom > e && that.data.item_height_list[i].top >= e) {
        for(let j = 0; j < that.data.opacity_list.length; j++){
          if(i - (j + 1) >= 0){
            that.data.item_height_list[i - (j + 1)].opacity = that.data.opacity_list[j]
          }
          let a = parseInt(i)
          if(a + (j + 1) < that.data.list.length){
            that.data.item_height_list[a + (j + 1)].opacity = that.data.opacity_list[j]
          }
        }
        let a = parseInt(i)
        for (let j in that.data.item_height_list) {
          if (!(j >= a - that.data.opacity_list.length && j <= a + that.data.opacity_list.length)){
            that.data.item_height_list[j].opacity = 0
          }
        }
        that.setData({
          item_height_list: that.data.item_height_list
        })
        break;
      }
    }
  },
  //根据滚动距离滚动到选项中间
  itemToMid:function(e){
    let that = this
    console.log("执行了",e)
    for (let i in that.data.item_height_list) {
      if (that.data.item_height_list[i].bottom > e && that.data.item_height_list[i].top <= e) {
        console.log(that.data.item_height_list[i].bottom, that.data.item_height_list[i].top)
        if (i < that.data.mid_item - 1) {
          that.setData({
            scroll_into_view: 'cushion_top_' + i
          })
        } else {
          console.log(parseInt(i) - that.data.mid_item + 1)
          that.setData({
            scroll_into_view: 'item_' + (parseInt(i) - that.data.mid_item + 1)
          })
        }
        that.setData({
          picker_value : that.data.list[i]
        })
        break;
      }
    }
  },
  //初始化
  init:function(e){
    let that = this
    //先计算该选择器的高度(根据每项高度和项目个数计算)单位px
    //如果选择器个数填写为双数,则强制-1变为单数
    if (that.data.picker.choose_item_number % 2 == 0){
      that.setData({
        ['picker.choose_item_number'] : that.data.picker.choose_item_number - 1
      })
    }
    //通过乘积计算选择器高度
    that.setData({
      box_height : that.data.picker.choose_item_number * that.data.picker.choose_item_height
    })
    //计算选择器中间项应该是第几项
    that.setData({
      mid_item : (that.data.picker.choose_item_number + 1) / 2 
    })
    //初始化遮盖层透明阶梯透明度从(0.1到0.9)
    let unit = Math.round(80 / (that.data.mid_item - 1)) /**阶梯单元 */
    for(let i = 0; i < that.data.mid_item - 1; i++){
      that.data.opacity_list.push((80 - i  * unit) / 100)
    }
    that.setData({
      opacity_list: that.data.opacity_list
    })
    //初始化遮盖层列表
    for(let i = 0; i < that.data.opacity_list.length; i++){
      let row = {opacity: that.data.opacity_list[i]}
      that.data.cover_list.push(row)
    }
    that.data.cover_list.push({ opacity: 0 })
    for(let i = 0; i < that.data.opacity_list.length; i++){
      let row = { opacity: that.data.opacity_list[that.data.opacity_list.length - 1 - i] }
      that.data.cover_list.push(row)
    }
    that.setData({
      cover_list: that.data.cover_list
    })
    //初始化选择器中每一项高度
    //初始化选项透明度,用于突出选中选项
    for(let i in that.data.list){
      let row = { top: 0, bottom: 0};
      // let topBase = (that.data.mid_item - 1) * that.data.picker.choose_item_height//顶端空白区域占用大小
      let topBase = 0
      row.top = topBase + i * that.data.picker.choose_item_height
      if(i == that.data.list.length - 1){
        row.bottom = topBase + (parseInt(i) + 1) * that.data.picker.choose_item_height + 100
      }else{
        row.bottom = topBase + (parseInt(i) + 1) * that.data.picker.choose_item_height
      }
      that.data.item_height_list.push(row)
      that.setData({
        item_height_list: that.data.item_height_list
      })
    }
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    let that = this
    that.init();
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

WXML:

<view class="box" style="height:{{box_height}}px;width:{{picker.box_width}}px;background:{{picker.bgColor}};">
  <scroll-view class="scroll_box" scroll-y="{{true}}" scroll-with-animation="{{picker.scroll_animation}}" bindscroll="bindscrollevent" scroll-into-view="{{scroll_into_view}}" scrollTop='{{scrollTop}}'>
    <view wx:for="{{mid_item - 1}}" class="cushion" style="height:{{picker.choose_item_height}}px;line-height:{{picker.choose_item_height}}px;font-size:{{picker.choose_item_font_size}}px;color:{{picker.bgColor}}" id="cushion_top_{{index}}">·</view>
    <view wx:for="{{list}}" class="choose_item" style="height:{{picker.choose_item_height}}px;line-height:{{picker.choose_item_height}}px;font-size:{{picker.choose_item_font_size}}px;color:{{picker.choose_item_font_color}}" id="item_{{index}}">{{item}}</view>
    <view wx:for="{{mid_item - 1}}" class="cushion" style="height:{{picker.choose_item_height}}px;line-height:{{picker.choose_item_height}}px;font-size:{{picker.choose_item_font_size}}px;color:{{picker.bgColor}};" id="cushion_bottom_{{index}}">·</view>
  </scroll-view>
  <!-- 透明度遮盖 -->
  <view style="position: fixed;top: 0;left: 70px;width:60px;z-index:9" bindtouchmove="touchMove" >
    <view wx:for='{{cover_list}}' style="height: {{picker.choose_item_height}}px;width: 100%;background: {{picker.bgColor}};opacity: {{item.opacity}}" ></view>
</view>
</view>
<view>{{picker_value}}</view>

wxss:

.box{
}
.scroll_box{
  height: 100%;
  width: 100%;
}
.choose_item{
  width: 100%;
  text-align: center;
}
.cushion{
  width: 100%;
  text-align: center;
}
.zhegai{
  height: 30px;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background: #01356f;
  opacity: 0.9
}

效果图

需要修改选择器直接修改data中picker内属性即可。选项逐渐变浅的效果比较让人头疼,最初的做法是对list内每个选项都加一个属性代表该选项的透明度,每次滑动都会修改显示的选项透明度,但是实际使用起来发现给选项赋值透明度的过程非常明显,导致体验不好。最后采用了现在这种方法,在文字上加了一排遮盖的view,这些view有不同的透明度从而展示出来渐变的效果,省去了每次滑动都要给选项修改透明度的烦恼。

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

(0)

相关推荐

  • 微信小程序 滚动选择器(时间日期)详解及实例代码

    微信小程序  滚动选择器(时间日期)详解 微信小程序自己封装了很多控件,用起来确实很方便,如果这是Android里面,还需要自己去定义,不废话,效果图: 一起来看看怎么实现的呢?看完你应该就该说,尼玛,这就行啦-. 这个效果呢,要用到picker组件,动画从底部弹起的滚动选择器,现支持三种选择器,通过mode来区分,分别是普通选择器,时间选择器,日期选择器,默认是普通选择器. 看下相应的属性: 具体的来看看代码,布局: <view class="section" > <

  • 微信小程序实现自定义picker选择器弹窗内容

    微信小程序中定义好的几种picker选择器,不管是日期选择器还是地区选择器,或是其他的都有定死的样式和内容. 例如: 但是大多数开发程序的情况下还是需要自己写样式的,或是内容的. 例如: wxml <view class="free-btns" style="margin-top: 10vh;background:none;"> <button class="free-btn" bindtap="toggleDialo

  • 微信小程序 选择器(时间,日期,地区)实例详解

    微信小程序 选择器(时间,日期,地区) 微信小程序 开发由于本人最近学习微信小程序的开发,根据自己的实践结果整理了下结果,对日期选择器,时间选择器,地区选择器做的实例,有不对的地方,希望大家指正. 用微信封装好的控件感觉很好,为我们开发人员省去了很多麻烦.弊端就是不能做大量的自定义.今天试用了选择器. 上gif: 上代码: 1.index.js //index.js //获取应用实例 var app = getApp() Page({ data: { date: '2016-11-08', ti

  • 微信小程序三级联动地址选择器的实例代码

    本文介绍了微信小程序三级联动地址选择器的实例代码,分享给大家,有需要的可以一起了解一下 在一些电商类的小程序中,地址选择这个功能一般是必备的,一般的收货信息都需要有一个能选择省市县的控件,当然也有些人为了省事就直接写了一个供输入的input,那么这样做的缺点不言而喻,而且用户体验也不是那么的好,今天的这篇文章就分享一下微信小程序地址选择的实现.省市县的数据以及区域码可以从国家统计局查询到,具体可以自己搜一下.照例先上源码和效果图 源码传送门 picker和picker-view组件 在正式介绍实

  • 微信小程序日期时间选择器使用方法

    本文实例为大家分享了精确到秒的微信小程序日期时间选择器,供大家参考,具体内容如下 效果图 实现原理 利用微信小程序的picker组件的多列选择器实现! WXML <view class="tui-picker-content"> <view class="tui-picker-name">时间选择器(选择时分)</view> <picker mode="time" value="{{time}}

  • 微信小程序 省市区选择器实例详解(附源码下载)

    微信小程序 省市区选择器:       最近学习微信小程序,为了检验自己的学习效果,自己做一个小示例,网上搜索下类似的实例,发现这个更好,大家看下. 一.区域间手势滑动切换,标题栏高亮随之切换 思路是:拿当前的current来决定高亮样式 1.监听swiper滚动到的位置: <swiper class="swiper-area" current="{{current}}" bindchange="currentChanged"> cu

  • 微信小程序多列选择器range-key使用详解

    本文实例为大家分享了微信小程序多列选择器的具体代码,供大家参考,具体内容如下 <picker mode="multiSelector" bindchange="bindMultiPickerChange2" bindcolumnchange="bindMultiPickerColumnChange2" value="{{multiIndex}}" range="{{objectMultiArray}}"

  • 微信小程序switch开关选择器使用详解

    本文为大家分享了微信小程序switch开关选择器使用方法,供大家参考,具体内容如下 效果图 WXML <view class="tui-list-box"> <view class="tui-menu-list"> <text>状态:{{isChecked1}}</text> <switch class="tui-fr" checked="{{isChecked1}}" b

  • 微信小程序之picker日期和时间选择器

    下面来介绍小picker,分三种样式: 默认的自己可以定义数据的 mode="time"是时间选择器 mode="date"是日期选择器 跟其他的一样先来看下picker.wxml <view class="page"> <view class="page__hd"> <text class="page__title">picker</text> <te

  • 微信小程序三级联动选择器使用方法

    本文实例为大家分享了微信小程序三级联动选择器的具体代码,供大家参考,具体内容如下 效果图 实现原理 利用微信小程序的picker组件,其中: 1,普通选择器:mode = selector实现一级选择实例: 2,省市区选择器:mode = region实现省市区三级联动: 3, 多列选择器:mode = multiSelector实现二级和三级联动的10以内数字的乘法. WXML <view class="tui-picker-content"> <view clas

随机推荐