微信小程序自定義滾動(dòng)選擇器
本文實(shí)例為大家分享了微信小程序自定義滾動(dòng)選擇器的具體代碼,供大家參考,具體內(nèi)容如下
最近項(xiàng)目里有個(gè)需求要做個(gè)滾動(dòng)選擇器,在網(wǎng)上找了半天也沒(méi)找到合適的demo,沒(méi)辦法只能發(fā)揮我的聰明才智創(chuàng)造一個(gè),上代碼。
js:
// pages/xuanzeqi/xuanzeqi.js Page({ ? /** ? ?* 頁(yè)面的初始數(shù)據(jù) ? ?*/ ? 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,//選擇器的高度(非控制項(xiàng),自動(dòng)計(jì)算),單位px ? ? picker:{ //選擇器的控制變量 ? ? ? box_width: 200,//選擇器寬度,單位px ? ? ? choose_item_height: 30,//選擇器中每一項(xiàng)選項(xiàng)的高度,單位px ? ? ? choose_item_font_size:25,//選擇器中每一項(xiàng)選項(xiàng)字體大小,單位px ? ? ? scroll_animation: true,//是否使用動(dòng)畫(huà)過(guò)渡 ? ? ? choose_item_number: 13,//選擇器內(nèi)選項(xiàng)的個(gè)數(shù)(要求為單數(shù)) ? ? ? bgColor:'#01356f',//選擇器的背景顏色 ? ? ? choose_item_font_color:'white',//選擇器選項(xiàng)的字體顏色 ? ? }, ? ? mid_item:0, ? ? scroll_into_view:'item_0',//滾動(dòng)到選項(xiàng)的id ? ? item_height_list:[],//存儲(chǔ)每一項(xiàng)距離頂端的y軸數(shù)據(jù) ? ? 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); ? }, ? //監(jiān)聽(tīng)選擇器滾動(dòng)事件 ? 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("滑動(dòng)結(jié)束"); ? ? ? // 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; ? ? ? } ? ? } ? }, ? //根據(jù)滾動(dòng)距離滾動(dòng)到選項(xiàng)中間 ? itemToMid:function(e){ ? ? let that = this ? ? console.log("執(zhí)行了",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 ? ? //先計(jì)算該選擇器的高度(根據(jù)每項(xiàng)高度和項(xiàng)目個(gè)數(shù)計(jì)算)單位px ? ? //如果選擇器個(gè)數(shù)填寫(xiě)為雙數(shù),則強(qiáng)制-1變?yōu)閱螖?shù) ? ? if (that.data.picker.choose_item_number % 2 == 0){ ? ? ? that.setData({ ? ? ? ? ['picker.choose_item_number'] : that.data.picker.choose_item_number - 1 ? ? ? }) ? ? } ? ? //通過(guò)乘積計(jì)算選擇器高度 ? ? that.setData({ ? ? ? box_height : that.data.picker.choose_item_number * that.data.picker.choose_item_height ? ? }) ? ? //計(jì)算選擇器中間項(xiàng)應(yīng)該是第幾項(xiàng) ? ? 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 ? ? }) ? ? //初始化選擇器中每一項(xiàng)高度 ? ? //初始化選項(xiàng)透明度,用于突出選中選項(xiàng) ? ? 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//頂端空白區(qū)域占用大小 ? ? ? 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 ? ? ? }) ? ? } ? }, ? /** ? ?* 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面加載 ? ?*/ ? onLoad: function (options) { ? ? let that = this ? ? that.init(); ? }, ? /** ? ?* 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面初次渲染完成 ? ?*/ ? onReady: function () { ? }, ? /** ? ?* 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面顯示 ? ?*/ ? onShow: function () { ? }, ? /** ? ?* 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面隱藏 ? ?*/ ? onHide: function () { ? }, ? /** ? ?* 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面卸載 ? ?*/ ? onUnload: function () { ? }, ? /** ? ?* 頁(yè)面相關(guān)事件處理函數(shù)--監(jiān)聽(tīng)用戶(hù)下拉動(dòng)作 ? ?*/ ? onPullDownRefresh: function () { ? }, ? /** ? ?* 頁(yè)面上拉觸底事件的處理函數(shù) ? ?*/ ? onReachBottom: function () { ? }, ? /** ? ?* 用戶(hù)點(diǎn)擊右上角分享 ? ?*/ ? 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內(nèi)屬性即可。選項(xiàng)逐漸變淺的效果比較讓人頭疼,最初的做法是對(duì)list內(nèi)每個(gè)選項(xiàng)都加一個(gè)屬性代表該選項(xiàng)的透明度,每次滑動(dòng)都會(huì)修改顯示的選項(xiàng)透明度,但是實(shí)際使用起來(lái)發(fā)現(xiàn)給選項(xiàng)賦值透明度的過(guò)程非常明顯,導(dǎo)致體驗(yàn)不好。最后采用了現(xiàn)在這種方法,在文字上加了一排遮蓋的view,這些view有不同的透明度從而展示出來(lái)漸變的效果,省去了每次滑動(dòng)都要給選項(xiàng)修改透明度的煩惱。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
javascript下function聲明一些小結(jié)
function聲明一些東西,我們都知道function和var一樣是預(yù)處理的在js里面,但是到底什么是函數(shù)聲明呢,我們來(lái)看幾個(gè)例子2007-12-12JavaScript使用Blob文件流下載txt、pdf、圖片等文件,自定義下載文件名
JavaScript使用Blob文件流下載txt、pdf、圖片等格式文件,同時(shí)自定義下載文件名,2023-08-08使用SpreadJS快速清除Excel中工作表保護(hù)密碼
這篇文章主要為大家介紹了使用SpreadJS快速清除Excel中工作表保護(hù)密碼方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11JavaScript前端實(shí)現(xiàn)壓縮圖片功能
這篇文章主要介紹了JavaScript前端實(shí)現(xiàn)壓縮圖片功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03JavaScript高級(jí)程序設(shè)計(jì) 客戶(hù)端存儲(chǔ)學(xué)習(xí)筆記
JavaScript高級(jí)程序設(shè)計(jì) 客戶(hù)端存儲(chǔ)學(xué)習(xí)筆記,在客戶(hù)端用于存儲(chǔ)會(huì)話(huà)信息2011-09-09innerHTML,outerHTML,innerTEXT三者之間的區(qū)別
innerHTML,outerHTML,innerTEXT三者之間的區(qū)別...2007-01-01jacascript DOM節(jié)點(diǎn)——元素節(jié)點(diǎn)、屬性節(jié)點(diǎn)、文本節(jié)點(diǎn)
這篇文章主要介紹了jacascript DOM節(jié)點(diǎn)——元素節(jié)點(diǎn)、屬性節(jié)點(diǎn)、文本節(jié)點(diǎn),需要的朋友可以參考下2017-04-04javascript面向?qū)ο蟪绦蛟O(shè)計(jì)(一)
這篇文章主要介紹了javascript面向?qū)ο蟪绦蛟O(shè)計(jì),分享給大家一段代碼,注釋里講解的非常詳細(xì),有助于我們理解面向?qū)ο螅@里推薦給大家。2015-01-01基于substring()和substr()的使用以及區(qū)別(實(shí)例講解)
下面小編就為大家分享一篇基于substring()和substr()的使用以及區(qū)別實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12