微信小程序分类-左侧导航与右侧内容联动

  • Post author:
  • Post category:小程序




左侧导航与右侧内容联动





一、首先是点击左侧导航,我们右侧内容需要滑动至相应的位置。

思路是:点击左侧某一项,获取该元素的id,也就是左侧view的id,然后动态传到右侧内容的scroll-into-view,scroll-into-view的值为某个子元素的id,

这里的子元素说的是右侧的view,我们将左侧view的id和右侧view的id设置为同一个值时,这样当左侧id发生变化时,scroll-into-view会帮助我们将右侧view进行相应的变化。

如图:

数据不同,

data-id


=


‘a{

{item.id}}’

替换成你数据的参数id(左侧栏数据的id)



二、接下来是右侧滚动,左侧对应选中,也就是高亮。

思路是:既然是滚动,我们需要用到scroll-view中的bindscroll属性(绑定滚动事件,和bindtap点击事件类似,点击触发bindtap监听,滚动触发bindscroll监听),

每次右侧滚动时,我们需要计算当前滚动的高度,当滚动超过左侧分类商品在右侧中占据的高度时,我们将动态修改左侧导航的id。

实际上当数据都显示的时候,我们计算每一项分类在右侧占据的高度,当滚动超过这个高度时,我们就修改左侧导航的id,这样我们就实现了高亮。

如图:

需要注意的是以上的红色圈部分,两个图中的红色圈id要一样

计算右侧占据高度的方法是通过wx.createSelectorQuery()。

我的数据是{

{good}}这个,每个人的数据不一样,但方法是相通的,按照我的文字和图进行操作是一定可以实现的。



三、最后一点问题

我们在判断滚动的高度是否超出时,最好给最初的scrollTop加上10,因为如果为0,当我点击第二个分类时,滑动可能还没有超出第一个分类占据的高度,那么高亮就会发生计算错误;还有就时如果分类中后面的商品过少,滑动时高亮也没有发生变化,所以最好时在最后的一个分类上做一些处理,比如加上占据高度,如图。




源码部分



js:


data: {


winHeight:


0


,


good: [],


contentActive:





,


// 内容栏id


navActive:


0


,


// 导航栏选中id


heightArr: [],


containerH:


0


,


},


onLoad:


function


() {


//


获取窗口可用


高度


wx.getSystemInfo({


success: res => {


this


.setData({


winHeight: res.windowHeight


});


}


});


//


在请求网络数据之后里面———


this


.setData({


good: res


})


this


.setHeightArr();


});


//


在请求网络数据之后里面写以上——-


},


setHeightArr:


function


(){


let


query = wx.createSelectorQuery().


in


(


this


);


let


heightArr = [];


let


s =


0


;


query.selectAll(


‘.vertical-list’


).boundingClientRect((react) => {


react.forEach((res) => {


s += res.height;


heightArr.push(s)


});


this


.setData({


heightArr: heightArr


})


});


query.select(


‘.content’


).boundingClientRect((res) => {


// 计算容器高度


this


.setData({


containerH: res.height


})


}).exec();


},


onScroll(e) {


let


scrollTop = e.detail.scrollTop;


scrollTop +=


10


;


let


scrollArr =


this


.data.heightArr;


if


(scrollTop >= scrollArr[scrollArr.length –


1


] –


this


.data.containerH) {


return


}


else


{


for


(


let


i =


0


; i < scrollArr.length; i++) {


if


(scrollTop >=


0


&& scrollTop < scrollArr[


0


]) {


console.log(


‘==============aaa’


+ scrollTop +


“==”


+ scrollArr[


0


]);


this


.setData({


navActive:


0


})


}


else


if


(scrollTop >= scrollArr[i –


1


] && scrollTop < scrollArr[i]) {


console.log(


‘==============bbb’


+ scrollTop +


“==”


+ scrollArr[i]);


this


.setData({


navActive: i


})


}


}


}


},


chooseType:


function


(e) {


let


id = e.currentTarget.dataset.id;


let


index = e.currentTarget.dataset.index;


console.log(


‘=============id’


+ id +


“–”


+ index);


this


.setData({


toView: id,


navActive: index


})


},

wxml:


<


view


class


=


“book-box”>


<


view


class


=


“swiper-vertical-tab”>


<


scroll-view


class


=


‘swipter-nav’


scroll-y


=


“true”


style


=


“height:{

{winHeight}}px;”>


<


view


wx:for


=


“{

{good}}”


wx:key


=


“item”


class


=


“{

{index===navActive ? ‘active’ : ”}}”


bindtap


=


“chooseType”


data-id


=


‘a{

{item.id}}’


data-index


=


‘{

{index}}’>


{

{item.foodType}}


</


view


>


</


scroll-view


>


</


view


>


<


view


class


=


“content content-class”>


<


scroll-view


class


=


“swiper-vertical-box”


scroll-y


=


“true”


style


=


“height:{

{winHeight}}px;”


scroll-into-view


=


“{

{toView}}”


scroll-with-animation


=


“true”


bindscroll


=


“onScroll”>


<


view


class


=


“vertical-list”


id


=


“a{

{item.id}}”


wx:for


=


“{

{good}}”


wx:key


=


“foodType”


wx:for-index


=


“idx”>


<


text


class


=


“title”>


{

{item.foodType}}


</


text


>


<


block


wx:if


=


“{

{item.data.length}}”>


<


view


class


=


“type-detail”>


<


view


wx:for


=


“{

{item.data}}”


wx:key


=


“foodDetail”


wx:for-index


=


“jdx”>


<


navigator


url


=


“/pages/good/index?id={

{item.objectId}}”>


<


image


src


=


“{

{item.menu_logo}}”


mode


=


“aspectFill”></


image


>


<


view


class


=


“book-detail”>


<


text


>


{

{item.menu_name}}


</


text


>


<


view


>


<


text


class


=


“money”>


¥{

{item.price}}


</


text


>


<


view


class


=


“operations smallsize”>


销量:{

{item.sale_number}}


</


view


>


</


view


>


</


view


>


</


navigator


>


</


view


>


</


view


>


</


block


>


<


block


wx:else


>


<


view


class


=


‘noshop’>


暂无商品


</


view


>


</


block


>


</


view


>


</


scroll-view


>


</


view


>


</


view


>

wxss:


page


{


background:


#f0f0f0


;


font-family:


“微软雅黑”


,


Helvetica


,


Arial


,


“Hiragino Sans GB”


,


“Source Han Sans CN”


,


“PingFang SC”


,


Roboto


,


“Heiti SC”


,


“Microsoft Yahei”


,


sans-serif


;


background:


#fff


;


width:


100%


;


height:


100%


;


}


.book-box


.content


{


flex:


1


;


background:


#fff


;


height:


100%


;


}


.swiper-tab


{


margin-top:


10px


;


height:


20px


;


padding:


10px


0


;


background:


#fff


;


display:


flex


;


font-size:


17px


;


line-height:


20px


;


border-bottom:


1px


solid


#e6e6e6


;


}


.swiper-tab-list


{


flex:


1


;


text-align:


center


;


position:


relative


;


color:


#787878


;


}


.swiper-tab-list:first-of-type


{


border-right:


1px


solid


#c8c8c8


;


}


.swiper-tab-list.on


{


color:


#fa4b22


;


}


.swiper-tab-list.on::after


{


content:


“”


;


height:


2px


;


width:


100px


;


background:


#fa4b22


;


position:


absolute


;


left:


50%


;


margin-left:


-50px


;


bottom:


-10px


;


}


.book-box


{


width:


100%


;


height:


100%


;


position:


absolute


;


top:


0


;


left:


0


;


bottom:


0


;


display:


flex


;


overflow:


scroll


;


}


.book-box


,


.order-box


{


width:


100%


;


position:


relative


;


box-sizing:


border-box


;


}


.swiper-vertical-box


{


box-sizing:


border-box


;


flex:


1


;


}


.order-box


{


background:


#fff


;


}


.swiper-vertical-tab


{


width:


200


rpx


;


left:


0px


;


top:


0


;


height:


100%


;


}


.swiper-vertical-tab


view


{


height:


50px


;


font-size:


15px


;


color:


#505050


;


text-align:


center


;


box-sizing:


border-box


;


padding-top:


12px


;


}


.swiper-vertical-tab


{


background:


#eee


;


}


.swiper-vertical-tab


view.active


{


background:


#fff


;


}


.swiper-vertical-box


.vertical-list


{


/* height: 300px; */


}


.swiper-vertical-box


.vertical-list


.title


{


height:


40px


;


padding-left:


20px


;


background:


#f5f5f5


;


color:


#646464


;


line-height:


40px


;


font-size:


15px


;


display:


block


;


}


.type-detail


{


background:


#fff


;


}


.type-detail


>


view


{


border-bottom:


1px


solid


#e5e5e5


;


margin-left:


10px


;


overflow:


hidden


;


padding-left:


80px


;


box-sizing:


border-box


;


position:


relative


;


height:


92px


;


width:


100%


;


margin-bottom:


-1px


;


}


.type-detail


view


image


{


width:


70px


;


height:


70px


;


border-radius:


6px


;


margin-top:


10px


;


/* border: 1px solid #ccc; */


float:


left


;


margin-bottom:


10px


;


position:


absolute


;


left:


0


;


top:


0


;


}


.book-detail


{


padding-right:


20px


;


}


.book-detail


>


text


{


font-size:


15px


;


color:


#505050


;


margin-top:


10px


;


display:


block


;


text-overflow:


ellipsis


;


display:


-webkit-box


;


-webkit-box-orient:


vertical


;


-webkit-line-clamp:


2


;


overflow:


hidden


;


font-weight:


bold


;


}


.book-detail


button


,


.book-result-detail


button


{


float:


left


;


width:


27px


;


height:


28px


;


border-radius:


14px


;


}


.book-detail


>


view


text


{


float:


left


;


}


.book-detail


>


view


view


{


float:


left


;


}


.book-detail


>


view


{


width:


100%


;


overflow:


hidden


;


position:


relative


;


height:


28px


;


display:


flex


;


align-items:


center


;


justify-content:


space-between


;


}


.book-detail


button.reduce


,


.book-result-detail


button.reduce


{


background:


url


(


http://bmob-cdn-8770.b0.upaiyun.com/2017/03/01/3b2b07294075d7b78025de3a115733c1.png


)


no-repeat


;


background-size:


100%


auto


;


}


.book-detail


button.add


,


.book-result-detail


button.add


{


background:


url


(


http://bmob-cdn-8770.b0.upaiyun.com/2017/03/01/23438bf040336dd980b7bfdd294d0265.png


)


no-repeat


;


background-size:


100%


auto


;


}


.book-detail


.money


{


font-size:


15px


;


color:


#fa4b22


;


line-height:


27px


;


}


.operations


text


{


line-height:


27px


;


color:


#333


;


width:


35px


;


display:


block


;


text-align:


center


;


}


.Bill-layer


{


width:


100%


;


height:


100%


;


background:


#000


;


opacity:


0.5


;


position:


fixed


;


left:


0


;


top:


0


;


z-index:


1


;


}


.Bill


{


position:


fixed


;


left:


0


;


bottom:


0


;


width:


100%


;


z-index:


2


;


}


.takeBill


{


height:


50px


;


background:


#fff


;


position:


relative


;


}


.takeBill


.box-right


{


width:


120px


;


height:


52px


;


background:


#fa4d22


;


position:


absolute


;


right:


0


;


top:


-1px


;


border-radius:


0


;


color:


#fff


;


line-height:


52px


;


text-align:


center


;


}


.box-left


{


margin-left:


30px


;


}


.box-left


>


view


{


float:


left


;


}


.box-left


.tips


{


width:


30px


;


position:


relative


;


background:


url


(


http://bmob-cdn-8770.b0.upaiyun.com/2017/03/01/d2c8205d404de1228042eff53f758aed.png


)


no-repeat


left


12px


;


background-size:


100%


auto


;


height:


40px


;


position:


relative


;


}


.box-left


.tips


view


{


position:


absolute


;


right:


-5px


;


top:


7px


;


width:


20px


;


height:


20px


;


background:


#f55022


;


color:


#fff


;


border-radius:


10px


;


text-align:


center


;


line-height:


20px


;


font-size:


12px


;


}


.box-left


.moeny


{


color:


#fa4b22


;


font-size:


17px


;


margin-left:


10px


;


margin-top:


15px


;


}


.clearCart


{


height:


35px


;


text-align:


right


;


background:


#f5f5f5


;


}


.clearCart


button


{


background:


none


;


float:


right


;


color:


#646464


;


line-height:


35px


;


font-size:


14px


;


padding-left:


16px


;


background:


url


(


http://bmob-cdn-8770.b0.upaiyun.com/2017/03/01/b89dba9340a615f8805f9fa477898dfd.png


)


no-repeat


left


center


;


background-size:


13px


auto


;


}


.clearCart


button::after


{


border:


0


none


;


}


.book-result-detail


{


overflow:


hidden


;


}


.book-result-detail


>


view


{


background:


#fff


;


overflow:


hidden


;


height:


50px


;


padding-top:


10px


;


padding-left:


15px


;


box-sizing:


border-box


;


padding-right:


10px


;


border-bottom:


1px


solid


#e6e6e6


;


}


.book-result-detail


>


view


text


{


float:


left


;


}


.book-result-detail


>


view


view


{


float:


right


;


}


.food-detail


{


overflow:


hidden


;


height:


36px


;


line-height:


36px


;


}


.food-detail


>


text


{


float:


left


;


color:


#3c3c3c


;


font-size:


18px


;


display:


block


;


}


.food-detail


>


view


{


float:


right


;


}


.food-detail


>


view


text


{


font-size:


15px


;


color:


#999


;


}


.place


{


height:


5px


;


width:


100%


;


background:


#f0f0f0


;


}


.order-list


{


border-top:


1px


solid


#e6e6e6


;


border-bottom:


1px


solid


#e6e6e6


;


margin-top:


-1px


;


padding:


20px


15px


;


}


.order-list


>


text


{


color:


#3c3c3c


;


font-size:


17px


;


margin-bottom:


6px


;


display:


block


;


}


.order-list


.time


{


color:


#999


;


font-size:


13px


;


text-align:


right


;


}


.bdt


{


border-top:


1px


solid


#e6e6e6


;


}


.hidden


{


display:


none


;


}


.show


{


display:


block


;


}


.noshop


{


text-align:


center


;


margin:


40


rpx


;


font-size:


28


rpx


;


color:


#999


;


}

由于我是请求服务器数据,所以js中请求网络源码不能公开,本地源码可参考:https://github.com/LandQ123/littleProgressChooseGoods



版权声明:本文为zhouhangzooo原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。