移动端原生实现列表列固定横向滚动功能

功能介绍:

在移动端开发中,会用到列表作为信息展示方式,一般希望上下滚动时,可以固定表头,左右滚动时,可以固定最左列。

需求:

1、列表可以使用数组循环遍历;
2、上下滚动时,可以固定表头在最顶端显示;
3、左右滚动时,可以固定左边一列或多列可以固定显示;
4、列表的列宽允许在数组中设置;

思路:

1、页面使用四个dom元素分别存储四种元素:

1)固定在左上角,完全不参与滚动表头元素;
2)固定在顶部,只允许左右滚动表头元素;
3)固定在左侧,只允许上下滚动列元素;
4)右下角,左右上下均可随意滚动列元素;

2、表头数组与列表数据数组之间互相联系,表头属性可以控制列表列排序、列表宽度、是否为固定列等;

3、四个dom之间增加联动,使用@scroll、scrollLeft、scrollTop;

示意图:

列表固定滚动布局图

实现代码:

html代码:

<div class="table-box"><div class="listFlexSty"><div class="fixedHeadBox" :style="{width: fixedWid}"><divclass="thClass"v-for="(item, index) in fixedHead":key="index":style="{width: item.width, justifyContent:item.name === '名称'?'flex-start':'',padding:item.name === '名称'?'0 10px':''}"@click="thItemClick(item)"><div>{{item.name}}</div><div class="playIconSty"><div class="topArrow"></div><div class="bottomArrow"></div></div></div></div><divclass="nomalHeadBox"style="{width: 'calc(100% - ' + fixedWid + ')';}"><div ref="nomalHeadBox" @scroll="scrollHList"><div class="thClass" :style="{width: nomalWid}"><divclass="thClass"v-for="(item, index) in nomalHead":key="index":style="{width: item.width,padding:item.name === '折扣偏差'?'0 10px':''}"@click="thItemClick(item)"><div>{{item.name}}</div><div class="playIconSty"><div class="topArrow"></div><div class="bottomArrow"></div></div></div></div></div></div></div><div style="height: calc(100% - 40px); overflow: auto" id="dataBodyId"><div v-show="tBodyData.length!==0" class="listFlexSty"><div class="fixedListBox" :style="{width: fixedWid}"><div ref="fixedListBox" @scroll="scrollFList"><div class="rLineSty" v-for="(item, index) in tBodyData" :key="index"><divv-for="(it, inx) in fixedHead":key="inx":style="{width: it.width, justifyContent:it.name === '名称'?'flex-start':'',padding:it.name === '名称'?'0 10px':''}"class="thClass"><span v-if="it.prop === 'storeName' || it.prop === 'curDiscount'">{{item[it.prop]}}</span><spanv-if="it.prop === 'orderAmount' || it.prop === 'diffAmount'"v-format="'#,##0.##'">{{item[it.prop]}}</span><span v-if="it.prop === 'completionRate'">{{item[it.prop]}}%</span><spanv-if="it.prop === 'yearEarlier'":class="item[it.prop]<0?'downArrow':item[it.prop]>0?'upArrow':''">{{item[it.prop]}}%</span><span v-if="it.prop === 'diffDiscount'">{{item[it.prop]>0?'+':''}}{{item[it.prop]}}</span></div></div></div></div><divclass="nomalListBox"ref="nomalListBox":style="{width: 'calc(100% - '+fixedWid+')'}"@scroll="scrollList"><divclass="rLineSty":style="{width: nomalWid}"v-for="(item, index) in tBodyData":key="index"><divv-for="(it, inx) in nomalHead":key="inx":style="{width: it.width,padding:it.name === '折扣偏差'?'0 10px':''}"class="thClass"><span v-if="it.prop === 'storeName' || it.prop === 'curDiscount'">{{item[it.prop]}}</span><span v-if="it.prop === 'orderAmount' || it.prop === 'diffAmount'" v-format="'#,##0.##'">{{item[it.prop]}}</span><span v-if="it.prop === 'completionRate'">{{item[it.prop]}}%</span><spanv-if="it.prop === 'yearEarlier'":class="item[it.prop]<0?'downArrow':item[it.prop]>0?'upArrow':''">{{item[it.prop]}}%</span><span v-if="it.prop === 'diffDiscount'">{{item[it.prop]>0?'+':''}}{{item[it.prop]}}</span></div></div></div></div><div v-show="tBodyData.length>0 && !finished" class="bottomTip" @click="moreLoad"><span style="color: #999999">展开查看更多</span><van-icon name="arrow-down" color="#999999" /></div><div v-show="tBodyData.length>0 && finished" class="bottomTip"><span style="color: #999999">已加载完全部数据</span></div><div v-show="tBodyData.length===0" class="noData">暂无数据</div></div>
</div>

js代码:

data(){return {// 下面是首页底部列表数据相关字段tHeadData: [{ name: '名称', prop: 'storeName', width: '100px', isfixed: true },{ name: '总业绩(元)', prop: 'orderAmount', width: '80px' },{ name: '平均折扣', prop: 'curDiscount', width: '80px' },{ name: '同比', prop: 'yearEarlier', width: '60px' },{ name: '完成率', prop: 'completionRate', width: '80px' },{ name: '缺口(元)', prop: 'diffAmount', width: '100px' },{ name: '折扣偏差', prop: 'diffDiscount', width: '80px' }],tBodyData: [],fixedHead: [],nomalHead: [],fixedWid: '',nomalWid: ''}
},methods: {// 列表数据相关initData() {this.fixedHead = this.tHeadData.filter(item => {return item.isfixed;});this.nomalHead = this.tHeadData.filter(item => {return !item.isfixed;});this.initSize();},initSize() {let fwid = 0;let nwid = 0;this.fixedHead.forEach(item => {// 此处以px单位为例const len = item.width.length - 2;const width = item.width.substring(0, len) - 0;fwid += width;});this.nomalHead.forEach(item => {const len = item.width.length - 2;const width = item.width.substring(0, len) - 0;nwid += width;});this.fixedWid = fwid + 'px';this.nomalWid = nwid + 'px';},// 首页下方数据列表联动相关scrollHList() {this.$refs.nomalListBox.scrollLeft = this.$refs.nomalHeadBox.scrollLeft;},scrollFList() {this.$refs.nomalListBox.scrollTop = this.$refs.fixedListBox.scrollTop;},scrollList() {this.$refs.fixedListBox.scrollTop = this.$refs.nomalListBox.scrollTop;this.$refs.nomalHeadBox.scrollLeft = this.$refs.nomalListBox.scrollLeft;}
}

css代码:

.table-box {width: 100%;height: calc(100% - 80px);overflow: hidden;
}
.listFlexSty {display: flex;
}
.fixedHeadBox {height: 40px;line-height: 40px;color: #333333;font-size: 12px;
}
.nomalHeadBox {height: 40px;line-height: 40px;overflow: hidden;color: #333333;font-size: 12px;
}
.fixedListBox {height: 100%;overflow: hidden;color: #666666;font-size: 12px;
}
.nomalListBox {height: 100%;overflow: auto;color: #666666;font-size: 12px;
}
.thClass {display: flex;align-items: center;justify-content: flex-end;
}
.rLineSty {height: 34px;padding: 10px 0;display: flex;
}
.rLineSty > div {display: -webkit-box;-webkit-line-clamp: 2;overflow: hidden;
}/* 隐藏滚动条 */
/* 隐藏右边表格头部滚动条 */
.nomalHeadBox > div {overflow: auto;height: calc(100% + 10px);
}
/* 隐藏左边列表滚动条 */
.fixedListBox > div {overflow: auto;height: 100%;width: calc(100% + 10px);
}
.noDataNew {height: calc(100% - 40px);display: flex;align-items: center;justify-content: center;color: #999;font-size: 12px;
}

效果图:

列表固定滚动

注意: 代码里的方法thItemClick是列排序功能,与此文章无关,实现代码未贴出,除此之外,其他未贴出的代码均与此文章所讲功能无关,忽略即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/213839.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

离线环境下使用百度地图(vue版)(展示自己的地图瓦片)3.0版本api

1.下载自己想要的地图网片 (1)瓦片图下载 提取百度网盘中文件&#xff0c;然后运行exe文件&#xff0c;选择要下载的层级及地区即可 百度网盘链接&#xff1a;https://pan.baidu.com/s/16sOJ9ws7HCgNH3EMf7Ejyg?pwd0q0e 提取码&#xff1a;0q0e (2)将瓦片图映射到网上 推荐使…

Python-docx 深入word源码 自定义字符间距

代码和实现效果 from docx import Document from docx.oxml import OxmlElement from docx.oxml.ns import qn from docx.shared import Pt# 调整pt设置字间距 def SetParagraphCharSpaceByPt(run, pt1):通过修改word源码方式, 添加w:spacing标签直接通过调整pt来设置字符间距…

Blender学习--制作带骨骼动画的机器人

1. 首先创建一个机器人模型 时间关系&#xff0c;这部分步骤有时间补充 2. 然后为机器人创建一副骨架 时间关系&#xff0c;这部分步骤有时间补充 3.骨骼绑定 切换到物体模式&#xff0c;选中机器人头部&#xff0c;Shift选中骨骼&#xff0c;切换到姿态模式&#xff0c;&am…

SpringBoot集成系列--xxlJob

文章目录 一、搭建调度中心xxl-job-admin1、下载项目2、调整项目参数3、执行初始化数据库SQL4、启动项目5、访问 二、集成步骤1、添加xxl-job的依赖2、添加xxl-job的依赖3、配置执行器4、创建执行器5、开发任务1&#xff09;方式1&#xff1a;BEAN模式&#xff08;方法形式&…

RocketMQ源码

RocketMQ的核心三流程 启动流程 RocketMQ服务端由两部分组成NameServer和Broker&#xff0c;NameServer是服务的注册中心&#xff0c;Broker会把自己的地址注册到NameServer&#xff0c;生产者和消费者启动的时候会先从NameServer获取Broker的地址&#xff0c;再去从Broker发…

【自动驾驶】2023年度盘点:智能汽车、自动驾驶、车联网必读书

2023年&#xff0c;智能驾驶和新能源汽车行业仍然有着肉眼可见的新进展。自动驾驶技术继续尝试从辅助驾驶向自动驾驶的过渡&#xff0c;更重要的是相关技术成本的下降。根据《全球电动汽车展望2023》等行业报告&#xff0c;预计2023年平均成本将降至100美元/千瓦时以下&#xf…

成都工业学院Web技术基础(WEB)实验八:BOM、DOM基本操作

写在前面 1、基于2022级计算机大类实验指导书 2、代码仅提供参考&#xff0c;前端变化比较大&#xff0c;按照要求&#xff0c;只能做到像&#xff0c;不能做到一模一样 3、图片和文字仅为示例&#xff0c;需要自行替换 4、如果代码不满足你的要求&#xff0c;请寻求其他的…

【开源】基于Vue.js的就医保险管理系统

文末获取源码&#xff0c;项目编号&#xff1a; S 085 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S085。} 文末获取源码&#xff0c;项目编号&#xff1a;S085。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预…

最好的猫罐头品牌有哪些?精选的5款口碑好的猫罐头推荐!

对于一个刚入门的养猫小白来说&#xff0c;面对市面上琳琅满目的猫罐头选择确实让人头大。我们总想选到营养价值高的罐头&#xff0c;但又怕猫咪不喜欢吃&#xff0c;也担心选到不安全的产品。 最好的猫罐头品牌有哪些&#xff1f;根据我开宠物店7年的经验&#xff0c;今天我将…

「哈士奇赠书活动 - 46期」-『技术人修炼之道:从程序员到百万高管的72项技能(第2版)』

⭐️ 赠书 - 《技术人修炼之道&#xff08;第2版&#xff09;》 ⭐️ 内容简介 本书旨在帮助计算机IT技术人员提升职场核心技能、架构思维、团队管理能力、商业认知&#xff0c;让每一位普通的技术从业者&#xff0c;修炼成为"技术职场超级个体”&#xff0c;通过全面升级…

IntelliJ IDEA无公网远程连接Windows本地Mysql数据库提高开发效率

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…

windows启动出现 zookeeper此处不应有java

可能是Java 路径出了问题&#xff0c;这个programFiles直接有空格&#xff0c;没错就有空格&#xff0c;笔者一开始以为这么点算什么空格&#xff0c;需要把这个对应的Java文件到别的英文路径下&#xff0c;并且修改环境变量。就可以启动的。 还可以启动方式有很多种&#xff0…

2.2 模型基础

建模流程 作业 这次搞了10天左右终于把作业做完了。 先是去学习了下如何建模->然后将模型导入Substance Painter里绘制贴图->最后导入到unity中&#xff08;虽然最后效果很差&#xff09;&#xff0c;但是回过头来看整个过程学习到了次时代美术的工作流&#xff0c;思考…

658. 找到 K 个最接近的元素

658. 找到 K 个最接近的元素 Java代码&#xff1a;滑窗 class Solution {public List<Integer> findClosestElements(int[] arr, int k, int x) {List<Integer> list new ArrayList<>();for (int i 0; i < arr.length; i) {arr[i] arr[i] - x;}for(i…

简单实现Spring容器(二) 封装BeanDefinition对象放入Map

阶段2: // 1.编写自己的Spring容器,实现扫描包,得到bean的class对象.2.扫描将 bean 信息封装到 BeanDefinition对象,并放入到Map.思路: 1.将 bean 信息封装到 BeanDefinition对象中,再将其放入到BeanDefinitionMap集合中,集合的结构大概是 key[beanName]–value[beanDefintion…

MySQL行锁范围分析(行锁、间隙锁、临键锁)

MySQL 中锁的概念 排它锁&#xff08;Exclusive Lock&#xff09; X 锁&#xff0c;也称为写锁&#xff0c;若事务T对对象A加上X锁&#xff0c;则只允许T读取和修改A&#xff0c;其他任何事物都不能再对A 加任何锁&#xff0c;直到T释放A上的锁。 SELECT…FOR UPDATE 对读取的…

风控之Android设备指纹技术

标识性参数——Android ID、IMEI、OAID非标识性参数 非标识性参数——手机运营商 1 设备指纹 简单来讲&#xff0c;设备指纹是指用于标识出该设备的设备特征。可以是单一设备特征&#xff0c;也可以是多种设备特征的组合&#xff0c;以方便风控系统对设备的唯一性进行识别。…

产品入门第一讲:Axure的安装以及基本使用

&#x1f4da;&#x1f4da; &#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Axure》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有…

未来教师行业发展前景

亲爱的老师们&#xff0c;你是否对未来教师行业的发展前景感到好奇和期待&#xff1f;作为一名老师&#xff0c;我深知教育行业的重要性和挑战&#xff0c;但同时也看到了其中蕴含的巨大机遇。 一、技术融合与在线教育 技术的飞速发展正在改变着教育的面貌。在线教育平台的崛起…

用C语言了解文件那些下 ‘流‘ 事

本篇会加入个人的所谓‘鱼式疯言’❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言,而是理解过并总结出来通俗易懂的大白话,我会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的&#xff0c;可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 前言 &#…