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

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 总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

总结排查服务器上传下载慢的几种手段与查看服务器带宽的具体方法

一、排查服务器上传下载 最近出现的一个情况&#xff0c;服务器上传和下载比较慢&#xff0c;因此我排查了种种手段&#xff0c;特此记录下几种常见的手段。 1、使用speedtest-cli 测试网速&#xff1a; 该方法是测试网速的速度怎么样&#xff0c;看看是否真的慢&#xff1f; …

软考A计划-2023系统架构师-知识点集锦(4/4)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

Spring Security--自动登录

也就是remember me 在配置链上加一个 然后发送请求时加上:remember-me字段 value值可以为&#xff0c;ture&#xff0c;1&#xff0c;on 我们记住登录后&#xff0c;关掉浏览器再打开&#xff0c;访问一下接口&#xff0c;可以访问&#xff0c;说明记住登录成功了。 因为有的…

JavaScript:从入门到精通:初始JS

JS基本思想 1. 浏览器对 JS 支持2. JS程序的组成3. JS 开发工具 1. 浏览器对 JS 支持 &#x1f9e1;背景 1997年 微软和网景公司合作发布了 ECMAScript 的语言规范 从那时起&#xff0c;微软所有浏览器都支持ECMAScript 标准 1999年&#xff0c;ECMAScript 第三版&#xff0c;…

mybatis-plus用法(二)

(5条消息) mybatis-plus用法&#xff08;一&#xff09;_渣娃工程师的博客-CSDN博客 AR模式 ActiveRecord模式&#xff0c;通过操作实体对象&#xff0c;直接操作数据库表。与ORM有点类似。 示例如下 让实体类User继承自Model package com.example.mp.po; import com.bao…

【026】C++的内联函数、函数重载、函数的默认参数与占位参数

C的内联函数、函数重载、函数的默认参数与占位参数 引言一、内联函数1.1、声明内联函数1.2、宏函数和内联函数的区别1.3、内联函数的注意事项 二、函数重载2.1、函数重载的概述2.2、函数重载的条件2.3、函数重载的底层实现原理 三、函数的默认参数四、占位参数五、extern "…

量化投资 现代投资组合理论(MPT)

量化投资 现代投资组合理论&#xff08;MPT&#xff09; 问题&#xff1a;构建投资组合&#xff0c;达到目标收益率的同时拥有最小的 risk exposure. 有 J J J 个可交易证券&#xff0c;期望收益率为 R [ R 1 , ⋯ , R j ] T R[R_1,\,\cdots,\,R_j]^T R[R1​,⋯,Rj​]T&…

监控、审计和运行时安全

监控、审计和运行时安全 目录 文章目录 监控、审计和运行时安全目录1、分析容器系统调用&#xff1a;SysdigSysdig介绍安装sysdigsysdig常用参数sysdig常用命令Chisels(实用的工具箱)其它命令 2、监控容器运行时&#xff1a;FalcoFalco介绍Falco架构安装falco自定义扩展规则文件…

千万级入口服务[Gateway]框架设计(一)

本文将以技术调研模式编写&#xff0c;非技术同学可跳过。 文章目录 背景问题[不涉及具体业务]目标技术选型语言框架模式实现一&#xff1a;go 原生组件Demo 实现Benchwork 基准性能小结实现二&#xff1a;开源 go-plugin 附录入口服务演变 背景 在历史架构的迭代中&#xff…

Apache Kafka学习

目录 一、简介 1.概念&#xff1a; 2.kafka四大API&#xff1a; 3.Kafka消费模式 4.Kafka的基础架构 5.kafka文件存储方式 二、特性 三、优点 1.解耦 2.异步处理 3.流量削峰 4.数据持久化 5.顺序保证 6.可恢复性 四、名词解释 五、QA Q:如何保证数据高可靠、不…

从美颜算法到AI美颜SDK:美丽的背后隐藏着什么?

在年轻人的生活中&#xff0c;通过美颜SDK类型的美颜工具进行拍摄已经成为了一种全新的文化现象。时下&#xff0c;AI美颜、美颜SDK讨论热点极高&#xff0c;那么大家知道美颜算法和AI美颜到底有什么不同吗&#xff1f;它们背后隐藏着什么样的技术和思想&#xff1f; 一、美颜算…

在Windows11平台安装JDK11(双11)

目录 引言一、安装前说明1.系统要求2.多版本安装 二、JDK11安装三、安装成功验证1.验证2.Path环境变量 总结 引言 本文主要是详细讲解在 Windows 11 系统上安装 JDK 11&#xff0c;安装时有一些注意事项需要说明。与 JDK 8 的安装过程有少许不一样。 一、安装前说明 1.系统要…

Atair 柱状比例图

如何熟练掌握可视化库和应对使用过程的疑难问题&#xff1f; 基本用法不妨访问 GeeksforGeeks 疑难问题优先搜索 https://stackoverflow.com 尽量使用官方文档&#xff1a; numpy的学习访问 https://numpy.org/doc/stable/user/index.html 例如&#xff1a; 一则 altair 使用过…

小程序中半屏打开其他小程序,开发者工具调试半屏

前言&#xff1a; 有需要是在当前小程序中&#xff0c;点击操作时&#xff0c;如果他没有注册会员&#xff0c;则强制去另一个小程序去注册会员&#xff0c;注册成功在返回&#xff0c;在这期间&#xff0c;打开另一个小程序是半屏来展示的。 实现效果&#xff1a; 在a小程序中…

阿里4年测试经验分享 —— 测试外包干了3年后,我废了...

去年国庆&#xff0c;我分享了一次一位阿里朋友的技术生涯&#xff0c;大家反响爆蓬&#xff0c;感觉十分有意思&#xff0c;今天我来分享一下我另一位朋友的真实经历&#xff0c;是不是很想听&#xff1f; 没错&#xff0c;我这位朋友是曾经外包公司的测试开发&#xff0c;而…

React新版扩展特性

目录 Hooks 三个常用的Hook State Hook Effect Hook Ref Hook Context Router 6 声明式路由 编程式路由导航 Hooks (1) Hook是react 18.8.0版本新增的特性/语法 (2) 可以让我们在函数式组件中使用state以及其他的react特性 三个常用的Hook (1) State Hook: React.useSt…

使用javacv中的ffmpeg实现录屏

今天突发奇想&#xff0c;想自己写一个录屏的软件&#xff0c;上次写了一个专门录音的Demo&#xff0c;但是要把声音和视频放到一起合成一个mp4文件&#xff0c;着实有一点艰难&#xff0c;所以就打算使用ffmpeg来写一个&#xff0c;而这篇博客中会顺便谈一谈我碰到的各种坑。 …

HarmonyOS学习路之开发篇—Java UI框架(StackLayout)

StackLayout StackLayout直接在屏幕上开辟出一块空白的区域&#xff0c;添加到这个布局中的视图都是以层叠的方式显示&#xff0c;而它会把这些视图默认放到这块区域的左上角&#xff0c;第一个添加到布局中的视图显示在最底层&#xff0c;最后一个被放在最顶层。上一层的视图…

数据湖仓一体化架构:探究新一代数据处理的可能性

一、引言 随着大数据的快速发展&#xff0c;企业不断寻求高效、灵活和经济的方法来处理和管理海量数据。在这种背景下&#xff0c;数据湖和数据仓库这两种不同的架构模式各自展现出其独特的优势。而数据湖仓一体化架构&#xff0c;是对这两种模式优势的综合&#xff0c;为企业…

wenda+fess问答系统

1 安装conda 2 创建环境 conda activate --name wenda python3.8 3 安装依赖工具包 pip install -r requirements/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple pip install torch BeautifulSoup4 torchvision torchaudio pdfminer.six -i https://pypi.t…