「続きを読む」ボタンの文章の高さを可変的にしてボタンを設置する方法

「続きを読む」ボタンの情報を探していましたが、どうも高さが固定前提です。

下記のようなやつです。

-------
表示する文章←ここの高さ固定
「続きを読む」ボタン
隠す文章
-------

ただ、自分はその文章の量が変動かつ、さらに少ない場合もあります。

なので、文章サイズの量は固定できません。

ここで一旦いつもの実装パターンを確認します。

実装方針

  • 隠す文章をoverflow: hiddenする
  • 表示する文章のcssheightで決めておく
  • 「続きを読む」ボタンをjQueryで表示する文章の兄弟要素に加える
  • 「続きを読む」ボタンクリックで、隠す文章のoverflow: hiddenを解除する

やり方

自分のケースは、文章が固定じゃないので、サイト表示後に高さを取得すればいいです。

それだけです。

実装方針

  • 文章の高さを取得する
  • 想定している高さ以上の場合は、文章を隠す。(overflow: hiddenを加える)
  • 隠す文章の兄弟要素の下にDOM(ボタン)を作成する
  • クリックすると表示するイベントを仕込む

作ったjsがこれです。

export default class Readmore {
  constructor(targets, element, height, cssList, text) {
    this.targets = document.querySelectorAll(targets)
    this.element = element
    this.height = height
    this.cssList = cssList
    this.text = text
  }

  more() {
    this._hidden()
    this._createButton()
  }

  _createButton() {
    const self = this

    this.targets.forEach((target) => {
      const height = target.clientHeight
      if (height == self.height) {
        const element = document.createElement(self.element)
        self.cssList.forEach((klass) => {
          element.classList.add(klass)
        })
        element.innerHTML = self.text
        target.parentNode.insertBefore(element, target.nextSibling)

        const button = target.nextSibling
        button.addEventListener('click', () => {
          self._show(target)
          button.parentNode.removeChild(button)
        })
      }
    })
  }

  _hidden() {
    const self = this

    this.targets.forEach((target) => {
      const height = target.clientHeight
      if (height > self.height) {
        const style = target.style
        style.overflow = "hidden"
        style.maxHeight = `${self.height}px`
      }
    })
  }

  _show(target) {
    const style = target.style
    style.overflow = ""
    style.maxHeight = null
  }
}
import readMore from '../../lib/utils/readmore.js'

  const targets = ".foo"
  const element = "button"
  const height = 100
  const cssList = ["bar", "baz"]
  const text = "続きを見る"

  const ReadMore = new readMore(targets, element, height, cssList, text)
  ReadMore.more()

targetsっていう変数に対象となる場所を入れます。

文章の高さも可変的にしました。

他でも流用できそうな部分は変数で渡すようにしました。

これだと、他の場所でも使えるのではないでしょうか。

もっといい書き方やスマートなやり方があると思うので、いい方法があればぜひ教えてくださいm( )m