微信小程序实现一个文字展开收起功能

news2024/11/16 15:38:09

1.0 需求背景

需求很常见,就是当一行文字过多时,显示省略号,然后显示展开两个字,点击,文字完全展示开,点击收起,回到省略形式,如下图

在这里插入图片描述

2.0 需求分析

有了上图,应该能更好理解,让我们再来细致分析下思路:

  1. 一行省略号,这个没啥难度,css可以实现(至于多行,差别不大)
  2. 展开和收起,初步构想是,收起状态时是通过css控制的省略号,那展开时,我们可以移除省略号的css,这样只需要添加、移除类名即可
  3. 如何确定当前行是否有省略号?这个问题,之前想过字体大小+屏幕宽度来计算一行最多能放下多少个字,实际发现,不够准确,后面想到另外一种方案;
    通过两个盒子嵌套外面大盒子只有一行文字高度,并且溢出隐藏,内层盒子就正常显示,当内层盒子高度 > 外层盒子,那么一定有省略号,故可以确定如下结构
 <!-- 外层盒子,固定只显示一行 -->
<view class="outer" style="height: {{outerHeight}}{{outerHeight == 'auto' ? '' : 'px'}}">
 <!-- 内层盒子,正常摆放,但是要动态添加省略号类名 -->
  <view 
    class="inner {{ show ? '' : 'ellipsis' }} " 
    style="padding-right: {{ show ? '0' : paddingRight }}px;">
    {{text}}
  </view>
</view>
  1. **如何确定一行文字的高度呢?**由于考虑到组件的通用性,笔者这里想了一个办法,写一个dom,将其定位到页面看不见的地方,然后获取一下,并且这里面的字体大小由外部传入,这样就能保证,不管怎么设置都可以准确获取
    <!-- 用于获取一行高度dom -->
<view class="get-height" >
  获取一行高度的盒子
</view>

3.0 具体实现

上面列举了几个问题,以及解决思考,现在我们就来具体实现

首先,获取dom高度肯定是需要的,这里把它简单封装下

  /**
   * 获取dom信息
   * **/ 
  getHeight(selector) {
    return new Promise((resolve,reject) => {
      const query = wx.createSelectorQuery().in(this)
      query.select(selector).boundingClientRect(function(res){
        resolve(res) 
      }).exec()
    })
  },

剩下的,大概就是高度差的判断,决定是否有省略号,以及动态添加、移除css类名,这个过程不算复杂

其实还有一个问题,就是,当确定要显示省略号时,右边切换的dom是需要定位到当前行的末尾,同时,当前行业需要一个padding,而这个padding就是切换按钮的宽度,所以这里也有一点点逻辑

4.0 完整如下

html

<view class="intercept" style="font-size: {{fontSize}};" >
  <!-- 外层盒子,固定只显示一行 -->
    <view class="outer" style="height: {{outerHeight}}{{outerHeight == 'auto' ? '' : 'px'}}">
      <view 
        class="inner {{ show ? '' : 'ellipsis' }} " 
        style="padding-right: {{ show ? '0' : paddingRight }}px;">
        {{text}}
      </view>
    </view>
    <view 
      wx:if="{{ heightInfo.realHeight > heightInfo.baseHeight }}"
      class="collapse {{show ? 'collapse-fold' : ''}}"
      bindtap="toggle" >
      {{show ? '收起' : '展开'}}
    </view>
    <!-- 用于获取一行高度dom -->
    <view class="get-height" >
      获取一行高度的盒子
    </view>
</view>

js

// components/interceptText/interceptText.js.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    text: {
      type: String,
      value: ''
    },
    fontSize: {
      type: String,
      value: '28rpx'//  单位rpx
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    heightInfo: {
      baseHeight: 0,
      realHeight: 0
    },
    show: true,
    // 需要动态设置的外层盒子高度
    outerHeight: 0,
    paddingRight: 0
  },
  lifetimes: {
    async attached() {
      this.calculateHeight()
    },
  },
  /**
   * 组件的方法列表
   */
  methods: {
  /**
   * 动态获取展开文字宽度
   * 确保展开、收起文字能显示
   * **/ 
  async getCollapseWidth() {
    let res = await this.getHeight('.collapse')
    if(!res) return
    this.setData({
      paddingRight: `${res.width}` || 30
    })
  },  
  /**
   * 计算高度差,判断是否有省略号
   * **/ 
  async calculateHeight() {
    return Promise.all([this.getHeight('.get-height'),this.getHeight('.inner')]).then((res) => {
      let [baseRes,realRes] = res
      let baseHeight = parseInt(baseRes.height || 0)
      let realHeight = parseInt( realRes.height || 0)

      if(!baseHeight || !realHeight) {
        this.setData({
          outerHeight: 'auto',
        })
        return
      }
      this.setData({
        heightInfo: {
          baseHeight,
          realHeight
        },
        outerHeight: baseHeight,
        show: !(realHeight > baseHeight)
      })
      // 计算展开、收起
      wx.nextTick(() => {
        this.getCollapseWidth()
      })
    })
  },
  /**
   * 获取dom信息
   * **/ 
  getHeight(selector) {
    return new Promise((resolve,reject) => {
      const query = wx.createSelectorQuery().in(this)
      query.select(selector).boundingClientRect(function(res){
        resolve(res) 
      }).exec()
    })
  },
  /**
   * 展开状态切换
   * **/ 
  toggle() {
    this.setData({ 
      show: !this.data.show,
      outerHeight: this.data.show ? this.data.heightInfo.baseHeight : this.data.heightInfo.realHeight
    })
  },
  }
})

css

.intercept{
  position: relative;
}
.outer{
  overflow: hidden;
}
.get-height{
  position: absolute;
  z-index: -9999;
  top: -100%;
  left: -100%;
  height: auto;
}
.ellipsis{
  display: -webkit-box;
  text-overflow: ellipsis;
  overflow: hidden;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}
.collapse{
  position: absolute;
  right: 0;
  bottom: 0;
  width: fit-content;
  color: #1989fa;
}
.collapse-fold{
  position: unset;
}

5.0 总结

笔者认为,实现该功能的难点是如何判断当前行是否应该省略,这里采取一个高度差的办法,基本就没有兼容性问题,不过实际中发下,文字会有闪烁,这是因为高度都是动态计算导致的,展开、收起,可能改为插槽更合适点

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

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

相关文章

2023亚马逊云科技中国峰会之Serverless

序言 Amazon Web Services&#xff0c;是Amazon.com推出的一系列云计算服务。 它提供了一系列的基础设施服务、平台服务和软件服务&#xff0c;希望可以帮助我们更轻松地构建和管理基于云的应用程序。 今天来学习一下 Serverless 本文会介绍以下六个模块&#xff1a; 为什么会…

RocketMq 同组消费者 自动设置InstanceName

RocketMq 同组消费者 自动设置InstanceName 一、背景二、处理方法三、源码分析四、总结 一、背景 同组多于1个消费者&#xff0c;如果没单独设置instanceName,默认为DEFAULT。启动时会报如下错误&#xff1a; org.apache.rocketmq.client.exception.MQClientException: The co…

物联网工业触摸屏与防火墙的安全协作

1 前言 随着物联网技术的快速发展&#xff0c;物联网HMI不仅需要提供SCADA级功能库和控件库&#xff08;点击查看物联网HMI功能库和控件库的详细介绍&#xff09;&#xff0c;还需要具备强大的安全性能。虹科物联网HMI内置防火墙功能&#xff0c;识别和阻止未经授权的访问&…

PCI Express --- LTSSM

目录 1. 链路训练和状态机 1.1 Detect 状态 1.1.1 Detect.Quiet 子状态 1.1.2 Detect.Active 子状态 1.2 Polling 状态 1.2.1 Polling.Active 子状态 1.2.2 Polling.Compliance 子状态 1.2.2 Polling.Configuration 子状态 1.2.3 Polling.Speed 子状态 1.3 Configuration 状…

性能测试超细总结,如何才能做到有效压测?性能压测看这篇就够了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 目标制定以及业务…

java SSM 游戏资讯系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM 游戏资讯系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和 数据库&#xff0c;系统主要采用B…

3ds Max - Pivot Painter Tool

很久之前的笔记&#xff0c;整理归档&#xff1b; Pivot Painter Tool是3dsMax中的插件&#xff0c;主要是辅助将Mesh中每个Element生成自己的Pivot Position&#xff0c;方便如使用World Position Offset对每个Element进行精确控制&#xff0c;导入使用Pivot Painter Tool工具…

深入理解Linux虚拟内存管理(七)

系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核 Linux 设备驱动程序 Linux设备驱动开发详解 深入理解Linux虚拟内存管理&#xff08;一&#xff09; 深入理解Linux虚拟内存管理&#xff08;二&#xff09; 深入理解Linux虚拟内存管理&#xff08;三&#xff09; 深入理…

Linux系统和Windows系统下Python2代码转换为Python3代码工具使用指南

简介 本文主要介绍Linux系统和Windows系统下Python2代码转换为Python3代码工具2to3.py或2to3指令使用指南。 项目场景及问题描述 Python2的最后一个版本是2.7&#xff0c;在2020年彻底停止支持。有些环境不方便同时安装Python2和Python3&#xff0c;或者在使用Python3的环境…

【JVM】JVM 垃圾回收算法

文章目录 前言标记清除&#xff08;Mark-Sweep&#xff09;介绍优缺点 复制&#xff08;拷贝 Copying&#xff09;介绍优缺点 标记整理&#xff08;Mark-Compact&#xff09;介绍优缺点 前言 目前JVM中有三种常见的垃圾回收算法&#xff0c;分别是&#xff1a;标记清除、标记整…

Matter实战系列-----1.软硬件开发环境搭建

一、硬件方面 我使用的是一套xG21 BRD4180B和两块xG24 BRD4187C,如下图&#xff1a; 1.1 RCP&#xff1a; 芯片型号EFR32MG21A020F1024IM32 1.2 Matter Light/Switch over Thread&#xff1a; 芯片型号EFR32MG24B220F1536IM48 1.3 蓝牙5.0 USB dongle 注意由于Linux对蓝牙…

阿里、字节、网易面试必考,黑马【爆火】微服务项目发布

最近&#xff0c;收到一位粉丝投稿&#xff0c;他说&#xff1a;“阿里三面凉凉了&#xff0c;输在了微服务上。” 在看到微服务的面试题后&#xff0c;整个人都是懵的&#xff0c;发现没有经验的自己&#xff0c;一窍不通。 如今&#xff0c;微服务已经成为Java开发者必备的…

深入篇【C++】string类的常用接口介绍:标准库中的string类 【万字总结】

深入篇【C】string类的常用接口介绍&#xff1a;标准库中的string类 Ⅰ.string类介绍Ⅱ.string类的常用接口①.string类对象的常用构造1.string()2.string(const char*ch)3.string(const string& str)4.string(size_t n,char c)5.string(const string& str,size_t pos,…

想开发测试工具,应该如何入手?

何为测试工具&#xff1f;就是能辅助测试同学来完成特定的操作的工具&#xff0c;比如常见的如postman、Fiddler、Charles、jira&#xff0c;包括jmeter等&#xff0c;当然还包括公司自己开发的用例转换工具&#xff0c;造数工具&#xff0c;Mock工具或是平台等等。一般以应用程…

测试在“鸡头”和“凤尾”间如何选择?

经常在知乎上碰到这样的问题&#xff1a;同时拿到多个offer&#xff0c;公司有大有小&#xff0c;有创业型有成熟性&#xff0c;怎么在“鸡头”和“凤尾”间做选择&#xff1f; 为什么会纠结呢&#xff1f;通常创业型公司&#xff0c;给优秀的测试员的薪酬远高于市场平均值&…

“我只想找个测试岗,你却百般刁难我!”给我们带来的思考

最近看到一篇帖子&#xff0c;讲的是一个七八年的大龄测试员被公司补偿性裁员后&#xff0c;找工作的糟心经历。 原文是酱紫的&#xff1a; ---------------------------------------- 不管怎么说&#xff0c;我做测试也有七八年了&#xff0c;一直觉得自己的技术还是可以的&…

MongoDB实际场景应用

你要构建一个在线零售商店&#xff0c;这个店铺需要处理会员数据、订单数据以及商品数据等。为了保存和管理这些数据&#xff0c;你可以使用MongoDB。 目录 1. 设计数据模式 2. 插入数据 3. 查询数据 1. 设计数据模式 对于在线零售商店的数据&#xff0c;你可以设计三个Mo…

3年经验,面试测试岗20k都拿不到了吗?

我的情况 大概介绍一下个人情况&#xff0c;女&#xff0c;本科&#xff0c;三年多测试工作经验&#xff0c;懂python&#xff0c;会写脚本&#xff0c;会selenium&#xff0c;会性能&#xff0c;然而到今天都没有收到一份offer&#xff01;从年后就开始准备简历&#xff0c;年…

C#基于云计算SaaS模式的医学检验云LIS系统全套源码

一、云LIS系统概述&#xff1a; 云LIS系统是一种基于云计算技术的实验室信息管理系统&#xff0c;它的主要功能是管理实验室中的各种信息数据&#xff0c;包括样品数据、检测结果、仪器设备管理、质控管理等。 二、与传统的LIS系统相比&#xff0c;云LIS系统具有以下优势&…

考完PMP后,还有必要考NPDP吗?

PMP证书目前在国内有很高的知名度&#xff0c;报考人数也在逐年上升&#xff0c;可以说&#xff0c;几乎所有的项目经理都有过考PMP的计划。 但随着PMP的持证人数越来越多&#xff0c;不少考完PMP的项目经理&#xff0c;开始考虑要不要报名NPDP考试。 那么考完PMP后有必要考N…