中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

小程序如何實現全文收起功能

發布時間:2022-03-08 09:02:06 來源:億速云 閱讀:127 作者:iii 欄目:移動開發

這篇“小程序如何實現全文收起功能”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“小程序如何實現全文收起功能”文章吧。

一、需求

  • 位于多行文本右下角,展示”全文/收起“按鈕

  • “展開”和“收起”兩種狀態的切換

  • 當文本不超過指定行數時,不顯示”全文/收起“按鈕

  • 文本顯示【全文】展示狀態下,更新數據,文本不被收起

二、實現思路

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、初次版本

根據設計思路,立馬上手代碼

foldable.wxml

<view class="content">
  <view class="contentInner content-inner-class showArea {{!onFold ? 'text-clamp' + maxLine : ''}}">{{content}}</view>
  <view class="contentInner content-inner-class hideArea" style="width: {{width}}px">{{content}}</view>
  <view class="foldInner fold-class {{position === 'right' ? 'flex-end' : 'flex'}}" 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: ['content-inner-class', 'fold-class'],
  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()計算的高度會有存在是實際高低的兩倍的現象。導致會錯誤出現【全文】文字。然后文本從兩行增加到三行或者多行都沒問題,不太理解為什么會出現這個錯誤計算的現象。

為了彌補這個坑,我引入了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、最終版本

經過上一個版本,基本功能都已經實現。但是,如果文本超過最大行數,并且在展開全文的情況下,更新了文本,此時,全文/展開按鈕會展示錯誤。

通過分析代碼可知,在展開全文的狀態下更新了文本,此時.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()
},

以上就是關于“小程序如何實現全文收起功能”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

盐山县| 瑞昌市| 台前县| 天祝| 临朐县| 芮城县| 宣恩县| 阿合奇县| 扎鲁特旗| 望城县| 乡宁县| 图们市| 大丰市| 白银市| 台前县| 台湾省| 邓州市| 高青县| 屏东县| 邻水| 土默特右旗| 翁牛特旗| 广水市| 治县。| 永兴县| 咸丰县| 安吉县| 科尔| 宜都市| 花垣县| 万载县| 孟连| 新化县| 平泉县| 高台县| 鹤岗市| 伊宁市| 渑池县| 治多县| 乡城县| 达尔|