目录
一、需求
二、实现思路
1、多行文本截断
2、判断文本是否超出指定行数,显示全文 收起 按钮
三、代码实现
1、初次版本
2、修复版本
3、增强版本
4、最终版本
四、代码片段
首页 微信小程序 小程序开发 聊聊小程序怎么实现“全文收起”功能

聊聊小程序怎么实现“全文收起”功能

Mar 07, 2022 pm 07:45 PM
小程序

小程序怎么实现“全文收起”功能?下面本篇文章小程序实现多行文本“全文收起”功能的方法,希望对大家有所帮助!

聊聊小程序怎么实现“全文收起”功能

小程序里经常会碰到需要实现多行文本”全文收起“功能,在掘金上有搜索到用纯css实现。亲测:ios很完美,andriod上的无效

小程序社区有很多方案,目前在社区有看到一位大佬使用js动态计算告诉去实现,亲测大致有效果,测试后,在一些特殊情况下,计算会有误差,所以有更改些许代码。

一、需求

  • 位于多行文本右下角,展示”全文/收起“按钮
  • “展开”和“收起”两种状态的切换
  • 当文本不超过指定行数时,不显示”全文/收起“按钮
  • 文本显示【全文】展示状态下,更新数据,文本不被收起

二、实现思路

1、多行文本截断

主要用到用到 line-clamp,关键样式如下

.text-clamp3 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}
登录后复制

2、判断文本是否超出指定行数,显示全文 收起 按钮

编写两段文本,一段展示完整的文本A,一段展示使用 line-clamp省略后的文本B,因为B有被截取,因此B的高度相对较小。对比两段文本的高度,便可以知道文本是否超出两行

在小程序里,可以使用wx.createSelectorQuery()获取文本高度

js

const query = wx.createSelectorQuery().in(this);
query.selectAll(".showArea, .hideArea").boundingClientRect(res => {
console.log(res, 'res')
}).exec()
登录后复制

1.png

三、代码实现

1、初次版本

根据设计思路,立马上手代码

foldable.wxml

<view class="content">
  <view class="contentInner content-inner-class showArea {{!onFold ? &#39;text-clamp&#39; + maxLine : &#39;&#39;}}">{{content}}</view>
  <view class="contentInner content-inner-class hideArea" style="width: {{width}}px">{{content}}</view>
  <view class="foldInner fold-class {{position === &#39;right&#39; ? &#39;flex-end&#39; : &#39;flex&#39;}}" wx:if="{{showFold}}">
    <text class="fold" catchtap="handleFold">{{onFold ? unFoldText : onFoldText}}</text>
  </view>
</view>
登录后复制

foldable.js

/**
 * 长文本内容展开与收起
 * @param {String} content  长文本内容
 * @param {Number} maxLine  最多展示行数[只允许 1-5 的正整数]
 * @param {String} position  展开收起按钮位置[可选值为 left right]
 * @param {Boolean} foldable  点击长文本是否展开收起
 * @param { String } onFoldText 收缩时文字
 * @param { String } unFoldText 展开时文字
 * 
 */

Component({
  externalClasses: [&#39;content-inner-class&#39;, &#39;fold-class&#39;],
  properties: {
    content: {
      type: String,
      observer(val) {
        if (this.data.onReady) {
          this.getNodeClientReact()
        }
      }
    },
    maxLine: {
      type: Number,
      value: 1,
      observer(value) {
        if (!(/^[1-5]$/).test(value)) {
          throw new Error(`maxLine field value can only be digits (1-5), Error value: ${value}`)
        } else if (this.data.onReady) {
          this.getNodeClientReact()
        }
      }
    },
    position: {
      type: String,
      value: "left"
    },
    foldable: {
      type: Boolean,
      value: true
    },
    // 收缩时文字
    onFoldText: {
      type: String,
      value: "全文"
    },
    // 展开时文字
    unFoldText: {
      type: String,
      value: "收起"
    },
  },
  data: {
    width: null,
    onFold: false,
    showFold: false,
    onReady: false
  },
  lifetimes: {
    attached() {
      this.getNodeClientReact()
      this.setData({
        onReady: true
      })
    },
  },
  methods: {
    getNodeClientReact() {
      setTimeout(() => this.checkFold(), 10)
    },
    checkFold() {
      const query = this.createSelectorQuery();
      query.selectAll(".showArea, .hideArea").boundingClientRect(res => {
        let showFold = res[0].height < res[1].height;
        this.setData({
          width: res[0].width,
          showFold,
        })
      }).exec()
    },
    handleFold() {
      this.setData({
        onFold: !this.data.onFold
      })
    }
  }
})
登录后复制

foldable.wxss

.content {
  width: 100%;
  position: relative;
  overflow: hidden;
}

.contentInner {
  word-break: break-all;
  width: 100%;
  color: #2f3033;
  font-size: 30rpx;
  line-height: 1.35;
}

.hideArea {
  display: -webkit-box;
  overflow: hidden;
  position: fixed;
  top: 100vh;
  left: -100vw;
}

.foldInner {
  padding-top: 10rpx;
  color: #6676bd;
  font-size: 32rpx;
}

.foldInner .fold {
  cursor: pointer;
}

.text-clamp1 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
}

.text-clamp2 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.text-clamp3 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

.text-clamp4 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
}

.text-clamp5 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 5;
}
登录后复制

2、修复版本

正常情况下,此方法可行,但是在级别文字下,会计算错误。经过测试,可将 节点是.hideArea的内容定位在.showArea节点下可解决

foldable.wxss

.hideArea {
  display: -webkit-box;
  overflow: hidden;
  /* position: fixed;
  top: 100vh;
  left: -100vw; */
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  color: #fff;
}
登录后复制

3、增强版本

经过修复之后,本来是可以完美实现了,但是在测试过程中,第一次正常渲染是没有问题。但如果文本数据更新,会发现如果原来的文本从一行增加到两行时,使用wx.createSelectorQuery()计算的高度会有存在是实际高低的两倍的现象。导致会错误出现【全文】文字。然后文本从两行增加到三行或者多行都没问题,不太理解为什么会出现这个错误计算的现象。(期待大神能留言告知 ? )

2.png

为了弥补这个坑,我引入了lineHieght这个属性。

// foldable.js
Component({
    properties: {
        lineHieght: {
          type: Number,
          observer(value) {
            if (!(/^[0-9]*$/).test(value)) {
              throw new Error(`lineHieght field value can only be digits`)
            }
          }
        }
    }
})
登录后复制

通过lineHieght和最多可展示行数maxLine可以计算出,可在界面展示的最大高度。

// 文本可见的最大高度
const maxHeight = this.data.lineHieght * this.data.maxLine;
登录后复制

当然了,我们也需要适配不同的设备,而且通过wx.createSelectorQuery()计算出来的结果是以px为单位的。

所以,行高需要根据设备尺寸去改变。因为我们是以宽度是750px尺寸为设计稿的,所以根据wx.getSystemInfoSync()可以获取设备信息,进而转换成px的尺寸。

// foldable.js
changeRpxToPx(rpxInteger) {
  return wx.getSystemInfoSync().windowWidth / 750 * rpxInteger
},
登录后复制

因此,更新checkFold方法

checkFold() {
  const query = this.createSelectorQuery();
  query.selectAll(".showArea, .hideArea").boundingClientRect(res => {
    let showFold = res[0].height < res[1].height;
    const lineHeightToPx = this.changeRpxToPx(this.data.LineHeight);
    // 展示区域高度(即是可能会被截取的可见文字)
    const showAreaHeight = res[0].height;
    // 隐藏区域的高度(即是完整文本高度,偶然事件会计算错误)
    const hideAreaHeight = res[1].height;
    // 文本可见的最大高度
    const maxHeight = lineHeightToPx * this.data.maxLine;
    // 如果是一行文字,偶然计算错误,用行高判断
    if (this.data.LineHeight && showAreaHeight <= maxHeight) {
      showFold = hideAreaHeight > maxHeight
    }
    this.setData({
      width: res[0].width,
      showFold,
    })
  }).exec()
},
登录后复制

4、最终版本

经过上一个版本,基本功能都已经实现。但是,如果文本超过最大行数,并且在展开全文的情况下,更新了文本,此时,全文/展开按钮会展示错误。

3.png

4.png

通过分析代码可知,在展开全文的状态下更新了文本,此时.showArea节点和.hideArea节点的高度一致,执行代码let showFold = res[0].height < res[1].height;,会返回false,因此按钮会消失。

因此解决方案为:

// 如果文本超出最大行数,并且是显示全文的状态下,再次更新了文字
let onFold = false
if (showAreaHeight == hideAreaHeight && showAreaHeight > maxHeight) {
  showFold = true
  onFold = true
}
登录后复制

所以最终版本的checkFold方法是:

checkFold() {
  const query = this.createSelectorQuery();
  query.selectAll(".showArea, .hideArea").boundingClientRect(res => {
    let showFold = res[0].height < res[1].height;
    const lineHeightToPx = this.changeRpxToPx(this.data.LineHeight);
    // 展示区域高度(即是可能会被截取的可见文字)
    const showAreaHeight = res[0].height;
    // 隐藏区域的高度(即是完整文本高度,偶然事件会计算错误)
    const hideAreaHeight = res[1].height;
    // 文本可见的最大高度
    const maxHeight = lineHeightToPx * this.data.maxLine;
    // 如果是一行文字,偶然计算错误,用行高判断
    if (this.data.LineHeight && showAreaHeight <= maxHeight) {
      showFold = hideAreaHeight > maxHeight
    }
    // 如果文本超出最大行数,并且是显示全文的状态下,再次更新了文字
    let onFold = false
    if (showAreaHeight == hideAreaHeight && showAreaHeight > maxHeight) {
      showFold = true
      onFold = true
    }
    this.setData({
      width: res[0].width,
      showFold,
      onFold,
    })
  }).exec()
},
登录后复制

四、代码片段

经过多次测试,修改,最后附上代码片段:

https://developers.weixin.qq.com/s/GWj19vmC7oxp

各位大神如果有更好的建议,可留言哦~~~

【相关学习推荐:小程序开发教程

以上是聊聊小程序怎么实现“全文收起”功能的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

使用Python开发微信小程序 使用Python开发微信小程序 Jun 17, 2023 pm 06:34 PM

随着移动互联网技术和智能手机的普及,微信成为了人们生活中不可或缺的一个应用。而微信小程序则让人们可以在不需要下载安装应用的情况下,直接使用小程序来解决一些简单的需求。本文将介绍如何使用Python来开发微信小程序。一、准备工作在使用Python开发微信小程序之前,需要安装相关的Python库。这里推荐使用wxpy和itchat这两个库。wxpy是一个微信机器

小程序能用react吗 小程序能用react吗 Dec 29, 2022 am 11:06 AM

小程序能用react,其使用方法:1、基于“react-reconciler”实现一个渲染器,生成一个DSL;2、创建一个小程序组件,去解析和渲染DSL;3、安装npm,并执行开发者工具中的构建npm;4、在自己的页面中引入包,再利用api即可完成开发。

实现微信小程序中的卡片翻转特效 实现微信小程序中的卡片翻转特效 Nov 21, 2023 am 10:55 AM

实现微信小程序中的卡片翻转特效在微信小程序中,实现卡片翻转特效是一种常见的动画效果,可以提升用户体验和界面交互的吸引力。下面将具体介绍如何在微信小程序中实现卡片翻转的特效,并提供相关代码示例。首先,需要在小程序的页面布局文件中定义两个卡片元素,一个用于显示正面内容,一个用于显示背面内容,具体示例代码如下:&lt;!--index.wxml--&gt;&l

支付宝上线'汉字拾光-生僻字”小程序,用于征集、补充生僻字库 支付宝上线'汉字拾光-生僻字”小程序,用于征集、补充生僻字库 Oct 31, 2023 pm 09:25 PM

本站10月31日消息,今年5月27日,蚂蚁集团宣布启动“汉字拾光计划”,最近又迎来新进展:支付宝上线“汉字拾光-生僻字”小程序,用于向社会征集生僻字,补充生僻字库,同时提供不同的生僻字输入体验,以帮助完善支付宝内的生僻字输入方法。目前,用户搜索“汉字拾光”、“生僻字”等关键词就可以进入“生僻字”小程序。在小程序里,用户可以提交尚未被系统识别录入的生僻字图片,支付宝工程师在确认后,将会对字库进行补录入。本站注意到,用户还可以在小程序体验最新的拆字输入法,这一输入法针对读音不明确的生僻字设计。用户拆

uniapp如何实现小程序和H5的快速转换 uniapp如何实现小程序和H5的快速转换 Oct 20, 2023 pm 02:12 PM

uniapp如何实现小程序和H5的快速转换,需要具体代码示例近年来,随着移动互联网的发展和智能手机的普及,小程序和H5成为了不可或缺的应用形式。而uniapp作为一个跨平台的开发框架,可以在一套代码的基础上,快速实现小程序和H5的转换,大大提高了开发效率。本文将介绍uniapp如何实现小程序和H5的快速转换,并给出具体的代码示例。一、uniapp简介unia

用Python编写简单的聊天程序教程 用Python编写简单的聊天程序教程 May 08, 2023 pm 06:37 PM

实现思路x01服务端的建立首先,在服务端,使用socket进行消息的接受,每接受一个socket的请求,就开启一个新的线程来管理消息的分发与接受,同时,又存在一个handler来管理所有的线程,从而实现对聊天室的各种功能的处理x02客户端的建立客户端的建立就要比服务端简单多了,客户端的作用只是对消息的发送以及接受,以及按照特定的规则去输入特定的字符从而实现不同的功能的使用,因此,在客户端这里,只需要去使用两个线程,一个是专门用于接受消息,一个是专门用于发送消息的至于为什么不用一个呢,那是因为,只

小程序备案怎么操作 小程序备案怎么操作 Sep 13, 2023 pm 04:36 PM

小程序备案操作步骤:1、准备个人身份证复印件、企业营业执照复印件、法人身份证复印件等备案材料;2、登录小程序管理后台;3、进入小程序设置页面;4、选择“基本设置”;5、填写备案信息;6、上传备案材料;7、提交备案申请;8、等待审核结果,如果备案不通过要根据原因进行修改,并重新提交备案申请;9、备案后续操作即可。

微信小程序怎么弄会员 微信小程序怎么弄会员 May 07, 2024 am 10:24 AM

1、打开微信小程序,进入对应的小程序页面。2、在小程序页面中查找会员相关入口,通常会员入口在底部导航栏或个人中心等位置。3、点击会员入口,进入会员申请页面。4、在会员申请页面,填写相关信息,如手机号码、姓名等,完成信息填写后,提交申请。5、小程序方会对会员申请进行审核,审核通过后,用户即可成为微信小程序会员。6、作为会员,用户将享有更多的会员权益,如积分、优惠券、会员专属活动等

See all articles