小程序自制自带滑动条的表格组件
先上最终效果图,表格可以上下、左右滑动,表格内容宽度固定,高度自适应内容大小,附上滑动条,滑动条长度宽度也是自适应表格的。
在编写过程中遇到的难点
- 表格的编写,小程序无table标签,需要自己用view+flex布局编写。
- 表格内容宽度固定,长度自适应。
- 滚动条逻辑及代码编写。
- 滚动条的卡段优化。
- 小程序组件的编写及应用。
1. 表格的编写
之前写过一篇简单利用view以及flex布局编写表格的文章。
链接: 小程序绘制表格table(表头固定,可上下左右滑动).
2. 表格内容宽度固定 长度自适应
当把表格填写进去后发现当内容宽度大于表格宽度时,居然不会换行,直接溢出。。
后来搜索了一下发现view是不会自动换行的,需要在.th .tr样式里加上这句:
/* view换行 */
white-space: pre-line;
/* 内容文字居中 */
display: flex;
justify-content: center;
align-items: center;
text-align: center;
加上后就变成了这样:
3. 滚动条逻辑及代码编写
为什么要自制滑动条呢,明明微信的scrollview有自带滑动条的功能:
自带的滑动条很好,也足够我们用了,但是!为什么ios的横向滑动条不显示啊????我搜索了一番发现我不是个例,于是我就开始自己编写滑动条,对了记得把小程序自带的滑动条屏蔽,因为安卓用户是显示的。用show-scrollbar="false"也是不生效的,需要在wxss中添加以下代码片段:
/* 隐藏原有的进度条 */
::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
color: transparent;
}
滚动条的编写逻辑参考了这篇文章:https://www.cnblogs.com/jiechen/p/4712631.html
主要是抓准一个比例关系:滚动条总长度 :滚动条长度 = 层级2 :层级1
由于滚动条的总长度通常与层级1的高度一致,所以:滚动条的长度 = (层级1 * 层级1)/ 层级2
当表格滑动时,滑动条也要跟着滑动,因此我们需要计算出滑动条滑动的距离:
首先算出滑动比例 = 滑动条可滑动距离 / 表格可滑动距离;
即:滑动比例 =(滑动条总长度 - 滑动条长度)/(层级2 - 层级1)= (层级1 - 滑动条长度)/(层级2 - 层级1)
那么滑动条需要滑动的距离= 滑动比例 * 层级滑动的距离
层级滑动的距离小程序已经在scrollview组件中给了我们:
以上逻辑形成js代码片段如下:
data: {
// x滑动条
sliderWidth: '', //滑块宽度
barWidth: '', //滑动条宽度
totalWidth: '', //表格整体宽度
slideRatioX: '', //比例
slideLeft: '', //滑动距离
},
methods: {
getRatioX: function (e) {
var query = wx.createSelectorQuery().in(this);
var _totalWidth = 0;
// 获取整体表格宽度
query.select("#tableContent").boundingClientRect((res) => {
_totalWidth = res.width;
}).exec()
// 计算比例
query.select('#tableX').boundingClientRect((res) => {
var _barWidth = res.width; //滑动条总宽度
var _showWidth = (_barWidth * _barWidth) / _totalWidth; //计算滑块宽度
var _ratio = (_barWidth - _showWidth) / (_totalWidth - _barWidth); //滚动列表长度与滑条长度比例
this.setData({
sliderWidth: _showWidth, //滑块宽度
barWidth: _barWidth, //滑动条宽度
totalWidth: _totalWidth, //表格整体宽度
slideRatioX: _ratio, //比例
})
}).exec()
},
}
滑动事件:
//在<scroll-view>标签里加上bindscroll="getleft"
<scroll-view scroll-x="true" bindscroll="getleft">
//...
</scroll-view>
//滑动条的html
<view class="slidex">
<view class='slidex-bar' id="barWidth" style="width: {
{barWidth}}px;">
<view class="slidex-show" id="sliderWidth" style="width: {
{sliderWidth}}px;margin-left:{
{slideLeft}}"></view>
</view>
</view>
//js文件中
getleft: function (e) {
this.setDate({
slideLeft