Renderings:
Implementation process:
Set default scrollbars and scrollbar backgrounds
<view class="myscrollBlock">
<view class="myscrollBg">
</view>
<view class="myscroll" :style="`width:${scroll_width}rpx;left:${scroll_left}rpx;`">
</view>
</view>
.myscrollBlock {
position: relative;
width: 100rpx;
top: -30rpx;
left: 50%;
transform: translateX(-50%);
.myscrollBg {
width: 100rpx;
height: 8rpx;
background: rgba(197, 254, 255, 0.15);
position: absolute;
z-index: 2;
border-radius: 10rpx;
}
.myscroll {
height: 8rpx;
background: #1CD5CD;
border-radius: 10rpx;
position: absolute;
z-index: 3;
}
}
The actual total width of the container (listWidth) = (width + margin) * number of elements in the container
The existing width of the container (blockWidth) = The existing width of my container is 90 percent of the width of the screen
The width of the default scroll bar (scroll bar) = the existing width of the container / the actual total width of the container * 100
setMyScrooll() {
this.scroll_width =0;
this.scroll_left =0;
let listWidth = (110+24) * this.list.length
let blockWidth = uni.getStorageSync('sysTemInfo').screenWidth * 0.9
this.scroll_width = blockWidth / listWidth * 100
},
Install the vuescroll plugin
Vuescroll scroll bar plugin installation:
npm install vuescroll -S
According to the handleScroll time of the plug-in, dynamically obtain the scrolling progress
handleScroll(vertical, horizontal, nativeEvent) {
this.scroll_width = horizontal.barSize * 100
this.scroll_left = (1 - horizontal.barSize) * horizontal.process * 100
},
Note:
1. In order to hide the default scroll bar of IOS, I set a fixed outer layer height, and then overflow: hidden;
2. The height of the vuescroll component in the code must be written in the view, because the component will set the height to 100%, and writing it in css with low priority will cause failure
full page code
<template>
<view class="page" id="page">
<image class="xinBj" :src="xinBj"></image>
<view class="menuBlock">
<view class="menuItem" v-for="(item, index) in menus" :key="index" @click="chooseMenu(item, index)">
<view class="titleBlock">
<image v-if="item.show" class="menuBgIn" :src="menuIn"></image>
<image v-else class="menuBgNo" :src="menuNo"></image>
<view class="year" :class="item.show ? 'colorIn' : 'colorNo'" v-html="item.guideNameFull"></view>
</view>
<div v-if="item.show" class="offLineTable" style="">
<vuescroll class="listBlock" style="height:302rpx;" scrollingY="false" @handle-scroll="handleScroll" :ops="ops">
<view class="p_r" v-if="list.length>0">
<view class="listItem p_l" v-for="(itemm, indexx) in list" :key="indexx"
@click="chooseList(indexx, itemm)"
:style="listIdx === indexx ? `background-image:url(${itemBg}); background-repeat:no-repeat; background-size:100% 100%;-moz-background-size:100% 100%;` : ''">
<image class="listIcon" :src="listIdx === indexx ? itemm.icon : itemm.icon"
mode="heightFix">
</image>
<!-- colorIn colorNo-->
<view class="txt" :class="listIdx === indexx ? '' : ''">
{
{ itemm.guideDetailName }}
</view>
</view>
</view>
</vuescroll>
<view class="myscrollBlock">
<view class="myscrollBg">
</view>
<view class="myscroll" :style="`width:${scroll_width}rpx;left:${scroll_left}rpx;`">
</view>
</view>
</div>
</view>
</view>
</view>
</template>
<script>
import vuescroll from "vuescroll";
export default {
components: {
vuescroll
},
data() {
return {
xinBj: this.$config.imageUrl + "xinBj.jpg",
menuNo: this.$config.imageUrl + "fungusv2/menuNo.png?v=2",
menuIn: this.$config.imageUrl + "fungusv2/menuIn.png?v=2",
icon1_1: this.$config.imageUrl + "fungus/icon1_1.png",
icon1: this.$config.imageUrl + "fungus/icon1.png",
itemBg: this.$config.imageUrl + "fungusv2/itemBg.png",
menus: [],
menuIdx: 0,
listIdx: 0,
list: [],
guideNameFull: "",
scroll_process: 0,
scroll_width: 0,
scroll_left: 0,
ops: {
mode: "slide",
locking: true,
detectResize: true,
sizeStrategy: 'percent',
bar: {
// rgba(197,254,255,0.15)
// "#1CD5CD"
background: "#1CD5CD", //滚动条的背景颜色
opacity: 0,
keepShow: true, // 一直显示滚动条
size: '0',
// color:"#1CD5CD"
},
rail: {
background: 'rgba(197, 254, 255, 0.15)',
opacity: 0,
size: '0',
},
scrollPanel: {},
}
};
},
onLoad(option) {
console.log("option.openid");
if (option.openid) {
console.log(option.openid);
uni.setStorageSync("openid", option.openid);
} else {
uni.setStorageSync("openid", 123);
}
this.menuIdx = 0;
this.$common.Init.call(this, "");
// this.setData();
this.getListFungus();
console.log(location)
},
methods: {
setMyScrooll() {
this.scroll_width =0;
this.scroll_left =0;
let listWidth = this.list.length * 134
let blockWidth = uni.getStorageSync('sysTemInfo').screenWidth * 0.9
this.scroll_width = blockWidth / listWidth * 100
},
handleScroll(vertical, horizontal, nativeEvent) {
this.scroll_width = horizontal.barSize * 100
this.scroll_left = (1 - horizontal.barSize) * horizontal.process * 100
},
getText(str) {
let words = str.replace(/<[^<>]+>/g, "").replace(/ /gi, ""); //这里是去除标签
return words.replace(/\s/g, ""); //这里是去除空格
},
getListFungus() {
console.log(1);
this.$request(this.$api.fungus.listFungus).then((res) => {
console.log(res);
res.data.infos.forEach((item, index) => {
if (index == 0) {
item.show = true;
} else {
item.show = false;
}
if (item.guideDetail) {
item.guideDetail.forEach((itemm, indexx) => {
itemm.show = false;
});
}
});
this.menus = res.data.infos;
this.guideNameFull = this.menus[0].guideNameFull;
let list = this.menus[0].guideDetail;
this.list = list;
this.setMyScrooll()
});
},
chooseList(index, item) {
this.listIdx = index;
console.log(this.menus[index]);
console.log(item);
let params = {
first_button: this.getText(this.guideNameFull),
second_button: item.guideDetailName,
};
this.guidelines(params);
let url = `/pages/fungusGuide/fungusDetail?guideDetailId=${item.guideDetailId}`;
this.goOtherPages(url);
},
chooseMenu(item, index) {
this.listIdx = 0;
if (item.guideDetail) {
this.menus.forEach((e) => {
e.show = false;
});
item.show = true;
let list = this.menus[index].guideDetail;
this.list = list;
this.setMyScrooll()
this.guideNameFull = this.menus[index].guideNameFull;
let params = {
first_button: this.getText(this.guideNameFull),
};
this.guidelines(params);
} else {
uni.showToast({
title: "内容开发中, 敬请期待!",
icon: "none",
});
}
},
guidelines(params) {
this.$request(
this.$api.huoshi.ld_clinical_guidelines_fungus_button,
params
).then((res) => {
console.log(res);
});
},
},
};
</script>
<style lang="scss">
.page {}
.myscrollBlock {
position: relative;
width: 100rpx;
top: -30rpx;
left: 50%;
transform: translateX(-50%);
.myscrollBg {
width: 100rpx;
height: 8rpx;
background: rgba(197, 254, 255, 0.15);
position: absolute;
z-index: 2;
border-radius: 10rpx;
}
.myscroll {
height: 8rpx;
background: #1CD5CD;
border-radius: 10rpx;
position: absolute;
z-index: 3;
}
}
.colorIn {
color: #c5feff;
}
.colorNo {
color: #1cd5cd;
}
.offLineTable {
width: 90vw;
margin-left: 5%;
height: 290rpx;
overflow: hidden;
}
.listBlock {
width: 90vw;
.listItem {
display: flex;
flex-shrink: 0;
width: 228rpx;
height: 228rpx;
background: rgba(197, 254, 255, 0.1);
justify-content: center;
/*子元素水平居中*/
align-items: center;
/*子元素垂直居中*/
display: -webkit-flex;
text-align: center;
margin-right: 20rpx;
.listIcon {
height: 74rpx;
}
}
}
.txt {
font-size: 26rpx;
margin-top: 20rpx;
color: #1cd5cd;
}
.menuBlock {
width: 100vw;
position: relative;
padding-top: 20rpx;
.menuItem {
margin-bottom: 30rpx;
padding-bottom: 20rpx;
width: 100vw;
position: relative;
font-size: 32rpx;
background: rgba(197, 254, 255, 0.05);
.titleBlock {
display: flex;
flex-direction: row;
padding: 20rpx;
padding-top: 50rpx;
padding-bottom: 20rpx;
}
.year {
// margin-top: -10rpx;
margin-left: 20rpx;
position: relative;
z-index: 20;
}
.menuBgNo {
width: 40rpx;
height: 40rpx;
z-index: 9;
}
.menuBgIn {
width: 40rpx;
height: 40rpx;
z-index: 8;
}
}
}
</style>