首先说一下思路:
1.高度是通过一个二维数组存储的,所以我们只需要先通过自己的实际情况算出这个高度即可。
let arr = [
[0, 522, 1002],
[1602, 2004,2006,2010],
[2364, 2766],
[3126, 3528],
[3888, 4290]
]
2.点击的时候我们直接通过index就可以判断是哪一个了,感觉没啥好说的。主要说一下我碰到的bug吧。
bug:
1.点击的时候,右侧出现来回闪的情况下,这是由于滑动延迟造成的,不论是页面滑动还是区域滑动都会延迟的。
解决办法:
直接添加一个状态是点击还是滑动的。
<scroll-view bindscroll="rightScroll({{false}})">
rightScroll(type,e){ this.isClick = type; if(!this.isClick){ .... } }
2:首先刚开始是不能滑动的,他只有滑动等上方的车型和年款顶上去的时候才会滑动,我用了一个很简单粗暴的办法。也是添加状态了。通过页面滑动里面判断。
<scroll-view scroll-y="{{gun}}">
3.每次点击完以后右侧都得刷新他的高度,所以在给了类以后一定要记得刷新dom
clickBigCat(index,type){ this.isClick = type; this.gun = true; this.$apply(); if(this.leftBigCategoryCurrent != index){ this.leftShortCategoryCurrent = 0; } if(wx.pageScrollTo){ wx.pageScrollTo({ scrollTop: this.pageScrollTop }); } this.leftBigCategoryCurrent = index; this.rightTop = this.listArr[index][0]; this.$apply(); let that = this; wx.createSelectorQuery().select('.leftShortCategory').boundingClientRect(function (rect) { let letLeftShortHeight = rect.height; that.leftHeight = letLeftShortHeight + that.leftBigHeigth; that.$apply(); }).exec(); },
4.其实难点主要就在判断区间上(我自己感觉,我是新手),下方是我先写的小例子,在写到项目中的。
let arr = [
[0, 522, 1002],
[1602, 2004,2006,2010],
[2364, 2766],
[3126, 3528],
[3888, 4290]
]
let target = 2009;
let Index = [0,0];
let lastNumber = 0;
arr.map(function(value,index){
lastNumber = arr[index].length - 1
value.map(function(val,idx){
if(val < target){
if(value[idx+1] && value[idx+1] > target){
Index = [index,idx];
}else if(value[idx+1] == undefined && arr[index+1][0] > target){
Index = [index,lastNumber];
}
}
})
})
console.log(Index)
5.还有个特别注意的点,就是左侧点击的到时候会触发右侧的scroll-view事件,解决办法就是点击的时候给他一个判断,让他为true,然后再变为false,这样每次就会判断是不是点击的。简单来说,就是每次点击完成以后都判断为滑动。
//右侧滑动
rightScroll(type,e){ if(this.isClick){ this.isClick = type; return } }
本来以为完成了的
结果呢又发现了一个bug。。。。。
简直了!!!!
然后我又能怎么办呢
当然是接着想了
bug如下,页面滑动和自带的滑动一起用的话,最后上滑的时候用户是滑不上去卡着的,所以解决办法只能使用页面滑动了,自带的组件就不用了。
右侧改为粘性定位,左侧使用相对定位就行。不使用scroll-view组件完全ok的啦。很顺滑完美。
完整代码
<style scoped lang="scss">
.banner{
width: 750rpx;
height: 512rpx;
}
/*固定内容*/
.fiexdCon{
width: 720rpx;
background: #fff;
position: sticky;
margin-top: -128rpx;
padding-left: 30rpx;
.title{
display: flex;
align-items: center;
font-size: 30rpx;
font-family: PingFang SC;
font-weight: bold;
color: #212121;
padding-top: 16rpx;
view:nth-child(1){
margin-left: 16rpx;
}
image{
width: 65rpx;
height: 62rpx;
}
}
.models{
width:100%;
white-space: nowrap;
display: flex;
margin-top: 19rpx;
padding-bottom: 36rpx;
.modelsItem{
display: inline-block;
padding: 15rpx 25rpx 15rpx 25rpx;
background: #F8F8F8;
border-radius: 28rpx;
font-size: 20rpx;
font-family: PingFang SC;
font-weight: 400;
color: #8F8A8A;
line-height: 25rpx;
margin-left: 16rpx;
}
.modelsItem:nth-child(1){
margin-left: 0;
}
}
.models .active{
background: #FEF9F5;
border-radius: 27rpx;
color: #E4AF80;
}
}
/*产品*/
.leftCategory{
text-align: center;
.leftBigCategory{
width: 170rpx;
height: 84rpx;
line-height: 84rpx;
background: #FFFFFF;
font-size: 29rpx;
font-family: PingFang SC;
font-weight: bold;
color: #313131;
position: relative;
}
.leftBigCategory.active{
color: #D29B6C;
font-size: 33rpx;
border-radius: 0rpx 0rpx 25rpx 0rpx;
position: relative;
}
.trangle{
width: 0;
height: 0;
border-left: 7rpx solid transparent;
border-right: 7rpx solid transparent;
border-top: 8rpx solid #D29B6C;
position: absolute;
left: 50%;
top: 80%;
transform: translateX(-50%);
}
.leftShortCategory + .leftBigCategory{
border-radius: 0rpx 25rpx 0rpx 0rpx;
}
.leftShortCategory{
font-size: 21rpx;
font-family: PingFang SC;
font-weight: 500;
color: #959595;
padding-top: 10px;
padding-bottom: 10px;
view{
height: 48rpx;
line-height: 48rpx;
}
}
.leftShortCategory .active{
font-size: 25rpx;
color: #222222;
}
}
/*产品右侧*/
.nav_right{
box-sizing: border-box;
.mink::after{
display:block;content:'';clear:both;
}
.mink{
background: #fff;
height: 100%;
.minkTitle{
height: 84rpx;
line-height:84rpx;
font-size: 30rpx;
font-family: PingFang SC;
color: #222;
padding-left: 20rpx;
font-weight: 550;
}
}
}
.nav_right_items{
width:100%;
height: 240rpx;
box-sizing: border-box;
text-align: center;
color: #4a4a4a;
background: #fff;
.goodimg {
width: 230rpx;
height: 230rpx;
border-radius: 5rpx;
margin-right: 5rpx;
}
}
.price_box {
display: flex;
align-items: center;
justify-content: space-between;
.price_centent{
display: flex;
.original{
color: #666666;
}
}
}
.goodsInfo{
height: 230rpx;
width: 338rpx;
// width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
border-bottom: 2rpx solid #eeeeee;
padding-top: 20rpx;
padding-bottom: 10rpx;
.goodsname{
color: #222;
width: 100%;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
font-size: 28rpx;
text-align: left;
}
}
.nav_right_items .row {
display: flex;
justify-content: space-between;
align-items: center;
}
.nav_right_items .row .number_title {
margin: 36rpx 30rpx;
color: #222;
font-size: 28rpx;
}
.nav_right_items .row .number_wrap {
display: flex;
margin-right: 30rpx;
height: 64rpx;
border: solid 2rpx #d3d3d3;
border-radius: 5rpx;
}
.price_boxIcon {
width: 50rpx;
height: 50rpx;
padding-right: 20rpx;
}
</style>
<template>
<custom-nav-bar title="去改吧" leftArrow="{{true}}" fixed="{{true}}" zIndex="{{zIndex}}" transparent="{{transparent}}" ></custom-nav-bar>
<view class="container" style="margin-top: {{statusBarHeight}}rpx;">
<image src="http://qugai.oss-cn-shanghai.aliyuncs.com/宝马X2-2020款-26万-A.png1618647287936" class="banner"></image>
<view class="fiexdCon" style="top: {{navigationBarHeight+statusBarHeight}}rpx;border-radius: {{radius ? '30rpx 30rpx 0 0' : ''}}">
<!--logo 车名 车型-->
<view class="title">
<image src="http://qugai.oss-cn-shanghai.aliyuncs.com/bk.png1558063765972"></image>
<view>别克 /</view>
<view style="color: #E4AF80;margin-left: 12rpx;">28T</view>
</view>
<!--年款-->
<scroll-view scroll-x="true" class="models">
<block wx:for="{{modelList}}" wx:for-index="index" wx:for-item="item" wx:key="index">
<view class="modelsItem {{index == modelActive ? 'active' : ''}}" @tap="clickModel({{index}})">{{item.name}}</view>
</block>
</scroll-view>
</view>
<!--产品-->
<view style="position: sticky;top:{{navigationBarHeight + statusBarHeight + 176}}rpx;display: flex;">
<scroll-view scroll-y="true" style="height: {{leftHeight}}px;width: 170rpx;background: #F6F6F6;">
<view class="leftCategory">
<block wx:for="{{list}}" wx:for-index="index" wx:for-item="item" wx:key="index">
<view class="leftBigCategory {{leftBigCategoryCurrent == index ? 'active' : ''}}" @tap="clickBigCat({{index}},{{true}})">
{{item.name}}
<view class="trangle" wx:if="{{leftBigCategoryCurrent == index}}"></view>
</view>
<view class="leftShortCategory" wx:if="{{leftBigCategoryCurrent == index}}">
<view wx:for="{{item.shortcategory}}" wx:for-index="idx" wx:for-item="shortItem" wx:key="idx" class="{{leftShortCategoryCurrent == idx ? 'active' : ''}}" @tap="clickShortCat({{index}},{{idx}},{{true}})">{{shortItem.name}}</view>
</view>
</block>
</view>
</scroll-view>
<scroll-view scroll-y="{{gun}}" scroll-top="{{rightTop}}" scroll-with-animation="{{true}}" bindscroll="rightScroll({{false}})" style="flex: 1;height: {{rightHeight}}px;">
<view class="nav_right">
<view class='mink' wx:for="{{list}}" wx:for-index="index" wx:for-item="item" wx:key="index">
<view class="minkTitle">{{item.name}}</view>
<block wx:for="{{item.shortcategory}}" wx:for-index="one" wx:for-item="product" wx:key="one">
<block wx:for="{{product.list}}" wx:for-index="two" wx:for-item="itemCon" wx:key="two">
<view class="nav_right_items"><view class="row" hover-class="other-navigator-hover" @tap="intoDetail({{itemCon}})" >
<image class="goodimg" mode="aspectFill" src="{{itemCon.masterPic}}">
<view class="goodsInfo">
<view style="display: flex;margin-left:10rpx;">
<image wx:if="{{itemCon.isMember}}" style="width: 22rpx;height: 22rpx;margin: 10rpx 10rpx 0 10rpx" src="../../images/vip.png"/>
<text class="goodsname">{{itemCon.productName}}</text>
</view>
<view class="price_box">
<view class="price_centent">
<view class="price original" wx:if="{{itemCon.costPrice&&itemCon.sellingPrice}}" >
<text wx:if="{{Mode.operatingMode==Mode.Purchase}}" class="text22">采购价:<text>¥{{itemCon.costPrice}}</text></text>
<text wx:if="{{Mode.operatingMode==Mode.Tandan && priceConfig.config!='NO'}}" class="text22" >零售价:<text>¥{{itemCon.sellingPrice}}</text></text>
</view>
<view class="price original" wx:else>
<text class="text22" > 未上市 </text>
</view>
</view>
<image @tap.stop="addCar({{itemCon}})" wx:if="{{Mode.operatingMode==Mode.Purchase}}"
class="price_boxIcon" src="https://qugai.oss-cn-shanghai.aliyuncs.com/default/icon/app/gouwuche.png" >
<image @tap.stop="addCar({{itemCon}})" wx:else class="price_boxIcon" src="https://qugai.oss-cn-shanghai.aliyuncs.com/default/icon/app/gouwuche.png" >
</view>
</view>
</view> </view>
</block>
</block>
</view>
</view>
</scroll-view>
</view>
<!-- 如果产品不足一屏的时候,没有他,粘性定位不起作用-->
<view style="width: 100%;height: 100vh"></view>
</view>
</template>
<script>
import wepy from "wepy";
export default class Home extends wepy.page {
config = {
navigationBarTitleText: "去改吧",
navigationStyle:"custom",
navigationBarTextStyle:"black",
"usingComponents": {
"van-dialog": "../../components/vant/dialog/index",
"custom-nav-bar": "../../components/vant/custom-nav-bar/index",
},
};
data = {
transparent:true,//导航栏透明度
radius:true,
statusBarHeight:undefined,//电量的高度
navigationBarHeight:undefined,//导航栏的高度
list:[
{
name:'音响升级',
shortcategory:[
{
name:'音响',
list:[
{productName:"尼诺帕克N5系列音响第一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"尼诺帕克N5系列音响",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"尼诺帕克N5系列音响",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"尼诺帕克N5最后一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
]
},
{
name:'隔音',
list:[
{productName:"隔音第一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"隔音第二个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"隔音第三个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"隔音最后一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
]
},
{
name:'滴滴',
list:[
{productName:"滴滴第一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"滴滴第二个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"滴滴第三个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"滴滴第四个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"滴滴最后一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false}
]
},
]
},
{
name:'玻璃膜',
shortcategory:[
{
name:'玻璃膜壹号',
list:[
{productName:"玻璃膜壹号",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"玻璃膜壹号",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"玻璃膜最后一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
]
},
{
name:'玻璃膜二号',
list:[
{productName:"玻璃膜二号第一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"玻璃膜二号",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"玻璃膜二号最后一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
]
}
]
},
{
name:'车身膜',
shortcategory:[
{
name:'车身膜壹号',
list:[
{productName:"车身膜壹号第一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"车身膜壹号",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"车身膜壹号最后一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
]
},
{
name:'车身膜二号',
list:[
{name:"车身膜二号第一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{name:"车身膜二号",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{name:"车身膜二号最后一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
]
}
]
},
{
name:'行车记录仪',
shortcategory:[
{
name:'行车记录仪壹号',
list:[
{productName:"行车记录仪壹号第一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"行车记录仪壹号",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"行车记录仪壹号最后一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
]
},
{
name:'行车记录仪二号',
list:[
{name:"行车记录仪二号第一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{name:"行车记录仪",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{name:"行车记录仪最后一个",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
]
}
]
},
{
name:'脚垫',
shortcategory:[
{
name:'脚垫壹号',
list:[
{productName:"脚垫",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"脚垫",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
{productName:"脚垫",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
]
},
{
name:'脚垫二号',
list:[
{name:"脚垫",masterPic:"http://qugai.oss-cn-shanghai.aliyuncs.com/主图.jpg1616556140715",isMember:false},
]
}
]
},
],
leftBigCategoryCurrent:0,
leftShortCategoryCurrent:0,
leftHeight:undefined,//左侧高度
leftBigHeigth:undefined,//左侧大分类的高度
rightHeight:undefined,//右侧高度
rightTop:undefined,//右侧滑动高度
gun:false,
// 年款列表
modelList:[
{
name: "2020-2028款 (653T)",
id:223,
},
{
name: "2020-2027款 (653T)",
id:224,
},
{
name: "2020-2026款 (653T)",
id:226,
},
{
name: "2020-2024款 (653T)",
id:228,
},
{
name: "2020-2022款 (653T)",
id:229,
},
],
modelActive:0,
listArr:[],
isClick:false,
}
onLoad(options) {
this.scale = !wx.getStorageSync('scale') ? 2 : wx.getStorageSync('scale');
this.statusBarHeight = wx.getStorageSync('statusBarHeight');
this.navigationBarHeight = wx.getStorageSync('navigationBarHeight')
}
onShow(){
this.ready();
}
methods = {
onPageScroll: function (e) {
let scrollHeight = (520-this.navigationBarHeight-128)/this.scale;
// 导航栏透明度
if (e.scrollTop>scrollHeight) {
this.transparent = false;
this.radius = false;
this.gun = true;
}else {
this.transparent = true
this.radius = true;
this.gun = false;
}
// console.log(this.gun,'是否滚动')
},
// 点击年款
clickModel(index){
this.modelActive = index;
},
// 点击大分类
clickBigCat(index,type){
this.isClick = type;
this.gun = true;
this.$apply();
if(this.leftBigCategoryCurrent != index){
this.leftShortCategoryCurrent = 0;
}
if(wx.pageScrollTo){
wx.pageScrollTo({
scrollTop: this.pageScrollTop
});
}
this.leftBigCategoryCurrent = index;
this.rightTop = this.listArr[index][0];
this.$apply();
let that = this;
wx.createSelectorQuery().select('.leftShortCategory').boundingClientRect(function (rect) {
let letLeftShortHeight = rect.height;
that.leftHeight = letLeftShortHeight + that.leftBigHeigth;
that.$apply();
}).exec();
},
// 点击小分类
clickShortCat(index,idx,type){
this.isClick = type;
this.gun = true;
this.$apply();
this.leftShortCategoryCurrent = idx;
this.rightTop = this.listArr[index][idx];
// wx.pageScrollTo({
// scrollTop: this.pageScrollTop
// });
},
// 右侧滑动
rightScroll(type,e){
if(this.isClick){
this.isClick = type;
return
}
this.isClick = type;
console.log(type,'..........')
if(!this.isClick){
let target = e.detail.scrollTop;
let lastNumber = 0;
let that = this;
let Index = [this.leftBigCategoryCurrent,this.leftShortCategoryCurrent];
that.listArr.map(function(value,index){
lastNumber = that.listArr[index].length - 1 || 0;
value.map(function(val,idx){
if(val < target){
if(value[idx+1] && value[idx+1] > target){
Index = [index,idx];
}else if(value[idx+1] == undefined && that.listArr[index+1][0] > target){
Index = [index,lastNumber];
}
}
})
})
this.leftBigCategoryCurrent = Index[0];
this.leftShortCategoryCurrent = Index[1];
wx.createSelectorQuery().select('.leftShortCategory').boundingClientRect(function (rect) {
let letLeftShortHeight = rect.height;
that.leftHeight = letLeftShortHeight + that.leftBigHeigth;
that.$apply();
}).exec();
}
}
}
ready(){
var windowHeight = wx.getSystemInfoSync().windowHeight;
// let leftBigHeigth = 0;
let rightTitle = 0;
let rightProduct = 0;
let that = this;
that.pageScrollTop = that.navigationBarHeight + that.statusBarHeight + 176;
wx.createSelectorQuery().selectAll('.leftBigCategory').boundingClientRect(function (rect) {
that.leftBigHeigth = rect.reduce((sum, e) => sum + e.height || 0, 0)
}).exec();
wx.createSelectorQuery().select('.leftShortCategory').boundingClientRect(function (rect) {
let letLeftShortHeight = rect.height;
let leftHeight = that.leftBigHeigth + letLeftShortHeight;
that.leftHeight = leftHeight;
that.$apply();
}).exec();
this.rightHeight = windowHeight - (that.navigationBarHeight + that.statusBarHeight + 176)/this.scale;
wx.createSelectorQuery().select('.minkTitle').boundingClientRect(function (rect) {
rightTitle = rect.height;
}).exec();
wx.createSelectorQuery().select('.nav_right_items').boundingClientRect(function (rect) {
rightProduct = rect.height;
let listArr = [];
let arr = [];
let lastNumber = 0;
let Index = 0;
// 计算需要滚动的数组
for(let i = 0; i < that.list.length; i++){
for(let j = 0; j < that.list[i].shortcategory.length; j++){
if(j == 0){
if(lastNumber == 0){
arr[j] = 0;
}else {
arr[j] = (that.list[i-1].shortcategory[Index].list.length)*rightProduct + lastNumber;
}
} else{
if(j == 1){
arr[j] = arr[j-1] + (that.list[i].shortcategory[j-1].list.length)*rightProduct + rightTitle;
}else{
arr[j] = arr[j-1] + (that.list[i].shortcategory[j-1].list.length)*rightProduct;
}
}
}
listArr[i] = arr;
lastNumber = arr[arr.length-1];
Index = arr.length-1;
arr = [];
}
that.listArr = listArr;
that.$apply();
}).exec();
}
}
</script>