Maison  >  Article  >  Applet WeChat  >  Parlons de la façon dont les mini-programmes implémentent la fonction « réduction du texte intégral »

Parlons de la façon dont les mini-programmes implémentent la fonction « réduction du texte intégral »

青灯夜游
青灯夜游avant
2022-03-07 19:45:284577parcourir

Comment implémenter la fonction « Réduire le texte intégral » dans le mini programme ? Ce qui suit est un petit programme pour implémenter la fonction « Réduire le texte intégral » du texte multiligne. J'espère qu'il sera utile à tout le monde !

Parlons de la façon dont les mini-programmes implémentent la fonction « réduction du texte intégral »

Dans les petits programmes, nous rencontrons souvent le besoin d'implémenter la fonction "réduire le texte intégral" du texte multiligne. J'ai cherché sur Nuggets et j'ai découvert qu'elle peut être implémentée en utilisant pure CSS. Test perso : C'est parfait sur ios, mais ça ne marche pas sur android.

Il existe de nombreuses solutions dans la petite communauté des programmes. Actuellement, j'ai vu un grand gars de la communauté utiliser le calcul dynamique js pour me dire comment le mettre en œuvre. Le test personnel est généralement efficace. Dans certains cas, le calcul comportera des erreurs, il y a donc quelques changements de code.

1. Exigences

  • Situé dans le coin inférieur droit du texte multiligne, affichez le bouton « Texte intégral/Réduire »
  • Basculement entre les états « Développer » et « Réduire »
  • Lorsque le texte ne dépasse pas la nombre de lignes spécifié, pas de bouton Afficher "Texte intégral/Réduire"
  • Affichage du texte [Texte intégral] Dans l'état d'affichage, les données sont mises à jour et le texte n'est pas réduit

2. Idées d'implémentation

1. -troncation du texte en ligne

Principalement utilisé Pour line-clamp, les styles clés sont les suivants

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

2 Déterminez si le texte dépasse le nombre de lignes spécifié et affichez le bouton de réduction du texte intégral

Écrivez deux. paragraphes de texte, l'un pour afficher le texte complet A et l'autre pour afficher à l'aide de line-clampLe texte omis B, car B a été intercepté, donc la hauteur de B est relativement petite. En comparant la hauteur de deux morceaux de texte, vous pouvez savoir si le texte dépasse deux lignes

Dans le mini programme, vous pouvez utiliser wx.createSelectorQuery() pour obtenir la hauteur du textewx.createSelectorQuery()获取文本高度

js

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

Parlons de la façon dont les mini-programmes implémentent la fonction « réduction du texte intégral »

三、代码实现

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()计算的高度会有存在是实际高低的两倍的现象。导致会错误出现【全文】文字。然后文本从两行增加到三行或者多行都没问题,不太理解为什么会出现这个错误计算的现象。(期待大神能留言告知 ? )

Parlons de la façon dont les mini-programmes implémentent la fonction « réduction du texte intégral »

为了弥补这个坑,我引入了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、最终版本

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

Parlons de la façon dont les mini-programmes implémentent la fonction « réduction du texte intégral »

Parlons de la façon dont les mini-programmes implémentent la fonction « réduction du texte intégral »

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

因此解决方案为:

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

所以最终版本的checkFold

js

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()
},

Parlons de la façon dont les mini-programmes implémentent la fonction « réduction du texte intégral »

3. Implémentation du code

1. Première version

🎜Selon l'idée de conception, démarrez le code immédiatement🎜🎜🎜foldable.wxml 🎜🎜rrreee🎜🎜foldable.js🎜 🎜rrreee🎜🎜foldable.wxss🎜🎜rrreee

🎜2. Version corrigée🎜🎜🎜Dans des circonstances normales, cette méthode fonctionne, mais sous le niveau. texte, des erreurs de calcul se produiront. Après test, la solution peut être résolue en positionnant le contenu du nœud .hideArea sous le nœud .showArea🎜🎜🎜foldable.wxss🎜🎜rrreee

🎜3. Version améliorée🎜🎜🎜Après la réparation, elle aurait pu être parfaitement implémentée, mais lors du test, il n'y a eu aucun problème avec le premier rendu normal. Mais si les données texte sont mises à jour, vous constaterez que si le texte original passe d'une ligne à deux lignes, la hauteur calculée à l'aide de wx.createSelectorQuery() sera le double de la hauteur réelle. Par conséquent, le texte [Full text] n'apparaîtra pas correctement. Ensuite, le texte passe de deux lignes à trois lignes ou plus sans aucun problème. Je ne comprends pas pourquoi cette erreur de calcul se produit. (J'espère que le maître pourra laisser un message pour me le faire savoir ?)🎜🎜2 .png🎜🎜Afin de pallier cet écueil, j'ai introduit l'attribut lineHieght. 🎜rrreee🎜La hauteur maximale pouvant être affichée sur l'interface peut être calculée via lineHieght et le nombre maximum de lignes affichées maxLine. 🎜rrreee🎜Bien sûr, nous devons également nous adapter aux différents appareils, et le résultat calculé via wx.createSelectorQuery() est en px. 🎜🎜Ainsi, la hauteur de la rangée doit être modifiée en fonction de la taille de l'appareil. Parce que nous utilisons la largeur de 750px comme brouillon de conception, nous pouvons obtenir les informations sur le périphérique selon wx.getSystemInfoSync(), puis les convertir en px code> taille. 🎜rrreee🎜Par conséquent, mettez à jour la méthode <code>checkFold🎜rrreee

🎜4 Version finale🎜🎜🎜Après la version précédente, les fonctions de base ont été implémentées. Cependant, si le texte dépasse le nombre maximum de lignes et que le texte est mis à jour lors du développement du texte intégral, le bouton Texte intégral/Développer affichera une erreur. 🎜🎜Parlons de la façon dont les mini-programmes implémentent la fonction « réduction du texte intégral »🎜🎜🎜🎜On peut le voir en analysant le code, le texte est mis à jour dans l'état de développement du texte intégral. À ce stade, la hauteur du nœud .showArea et du nœud .hideArea sont cohérentes. .Exécutez le code let showFold = res[0] .height renverra <code>false, donc le bouton disparaîtra. 🎜🎜La solution est donc : 🎜rrreee🎜Donc la version finale de la méthode checkFold est : 🎜rrreee🎜Quatre extraits de code🎜🎜🎜Après de nombreux tests et modifications, l'extrait de code est enfin joint : 🎜🎜 https://developers.weixin.qq.com/s/GWj19vmC7oxp🎜

Si vous avez de meilleures suggestions, veuillez laisser un message~~~

[Recommandations d'apprentissage associées : Tutoriel de développement de mini-programmes]

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer