ホームページ  >  記事  >  WeChat アプレット  >  ミニプログラムが「全文折りたたみ」機能を実装する方法について話しましょう

ミニプログラムが「全文折りたたみ」機能を実装する方法について話しましょう

青灯夜游
青灯夜游転載
2022-03-07 19:45:284720ブラウズ

ミニプログラムに「全文折りたたみ」機能を実装するにはどうすればよいですか?以下は、複数行テキストの「全文折りたたみ」機能を実装するためのこの記事の小さなプログラムです。

ミニプログラムが「全文折りたたみ」機能を実装する方法について話しましょう

小規模なプログラムでは、複数行テキストの「全文折りたたみ」機能を実装する必要があることがよくあります。Nuggets で検索したところ、実装できることがわかりました。 純粋な css を使用します。個人的なテスト: ios は完璧ですが、android では動作しません。

小規模なプログラム コミュニティには多くのソリューションがあります。現在、コミュニティの大物が js 動的計算 を使用して実装方法を教えてくれているのを見かけました。個人的なテストは一般的に次のとおりです。テスト後、特殊な状況では計算にエラーが発生するため、一部のコードを変更する必要があります。

1. 要件

  • 複数行テキストの右下隅にある「全文/折りたたみ」ボタンを表示します
  • 「展開」 「折りたたむ」2 状態の切り替え
  • テキストが指定行数を超えない場合、「全文/折りたたむ」ボタンは表示されません
  • テキスト表示で[全文]表示

2. 実装のアイデア

1. 複数行のテキストの切り詰め

##主に使用される line-clamp 、キーのスタイルは次のとおりです

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

2. テキストが指定行数を超えているかどうかを判断し、全文折りたたみボタンを表示します

テキストの 2 つの段落を記述します。1 つの段落には完全なテキスト A が表示され、A 段落には line-clamp を使用して省略されたテキスト B が表示されます。B がインターセプトされているため、B の高さは相対的に低くなります。小さい。 2 つのテキストの高さを比較すると、テキストが 2 行を超えているかどうかを知ることができます。

ミニ プログラムでは、wx.createSelectorQuery() を使用してテキストの高さを取得できます。

js

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

ミニプログラムが「全文折りたたみ」機能を実装する方法について話しましょう

3. コードの実装

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. 強化版

改修後は完璧に実装できたはずですが、テスト段階では最初の通常レンダリングでは問題ありませんでした。しかし、テキスト データを更新すると、元のテキストが 1 行から 2 行に増えると、

wx.createSelectorQuery() で計算される高さが実際の高さの 2 倍になることがわかります。その結果、[全文] テキストが正しく表示されません。するとテキストは問題なく2行から3行以上に増えますが、なぜこのような計算違いが起こるのか理解できません。 (マスターがメッセージを残して知らせてくれるといいのですが?)

ミニプログラムが「全文折りたたみ」機能を実装する方法について話しましょう

この落とし穴を補うために、属性

lineHigheght を導入しました。

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

インターフェイス上に表示できる最大の高さは、

lineHeight と表示可能な最大行数 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
},

したがって、

checkFoldmethod

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 ノードの高さと一致します。コードを実行すると、 let showFold = res[0].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()
},
4. コード スニペット

多くのテストと変更を経て、最終的にコード スニペットが添付されました:

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

より良い提案がある場合は、メッセージを残してください~~~

[関連する学習の推奨事項: 小さなプログラム開発チュートリアル]

以上がミニプログラムが「全文折りたたみ」機能を実装する方法について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。