JavaScript/CSS: 文字数オーバーしたときに「…」で表示する。

〽️ テキストボックスを整えよ。


レイアウトを崩したくない。

こんにちは、「ふ」です。
テキストの入ったボックスを表示する際。

テキストの文字数によって、要素全体の高さが変わってきます。
ボックスのサイズは不揃いとなり、横並びで表示したい場合などはレイアウトが崩れてしまいますね。




このように文字数が多い場合、オーバーした分を「…」で表示することができれば、要素のサイズは統一することができますね。twitterなどで使われているのを見かけます。

今回はその方法にチャレンジしたいと思います。



1行ならこれがある。

ここで、1行のものであれば、CSSのtext-overflowプロパティを使うことで解決します。
例えばこんなコード。

HTML

短いテキスト。

長いテキストだとはみ出してしまう。

CSS

.sample { width:50%; border:solid 2px blue; }
※bodyの幅は固定しています。

ブラウザ

普通にやるとこうなります。ここに、CSSを3行追加します。

CSS

.sample { width:50%; border:solid 2px blue; 「「3//改行の禁止」」 「「1white-space:nowrap;」」 「「3//はみ出した部分を隠す」」 「「1overflow:hidden;」」 「「3//テキストのはみ出しを「…」で省略」」 「「1 text-overflow:ellipsis;」」 }

ブラウザ

文字数に関わらず、要素の高さが統一されました。

text-overflowプロパティは、テキストのはみ出した部分をどのように表現するかを指定します。「ellipsis」は「省略記号」の意です。



問題は複数行。

ここで悲しい現実。

CSSのtext-overflowは、2行以上のテキスト領域には対応しません。

次のようなコードを見てみましょう。

HTML

長めのテキストだけど、2行に収まる。

これは長すぎるテキストだぞ。まずは私の生い立ちから話さなければなるまい。

ブラウザ

これらのテキストボックスを、2行サイズに統一したい⬇︎。

完成イメージ






CSSがダメなら、JavaScriptでなんとかしましょう。




作戦会議。

・2行分のスペースに何文字収納できるのかを取得

・文字数オーバーの場合、元のテキストから((収納可能な文字数)-1)を切り出し、末尾に「…」を付けてテキストを書き換える。

こういった作戦でいきたいと思います。






Go。




3行に広がってしまっているボックスに対して、これを2行に限定するとしたら収まる文字数はいくらになるのか。
要素を取得して、その値を検出します。

JavaScript

「「3//class要素を取得」」 var sample2 = document.getElementsByClassName("sample2"); 「「3//はみ出したボックスの現在のCSS」」 var style = window.getComputedStyle(sample2[1]); 「「3//フォントサイズとボックスの幅を数値で取得」」 var fontsize = parseInt(style.fontSize); var width = parseInt(style.width); 「「3//2行分のボックスに収納できる文字数」」 var mojisuu = Math.floor(width/fontsize)*2;

収納可能な文字数が取得できました。ためしに出力。

console.log(mojisuu); 「「1▶︎ 24」」

ここまでは順調ですね。では元のテキストを文頭から(「mojisuu」-1)文字分切り出して、末尾に「…」を連結します。テキストの切り出しには「substr( )」メソッドを使用しました。

「「3//元のテキストを取得」」 var str = sample2[1].innerText; 「「3//テキストから(「mojisuu」-1)文字を切り出し。」」 str = str.substr(0,(mojisuu-1)); 「「3//「…」と連結し、元のテキストを置き換える」」 sample2[1].innerText = str + "…";

扨(さて)、、実行してみましょう。




ブラウザ






できました!

やや強引(笑)な方法ですが、成功です。
全てのclass要素に適用させたい時は、for文の中で条件分岐させると良いでしょう。

「「3//「mojisuu」取得まではグローバルで記述。」」 for (i = 0; i < sample2.length; i++) { 「「3//もしテキストの文字数がオーバーしたら」」 if(sample2[i].innerText.length > mojisuu) { 「「3//テキストの取得/置き換え」」 var str = sample2[i].innerText; str = str.substr(0,(mojisuu-1)); sample2[1].innerText = str + "…"; } }


まだ完璧ではない。

ほんとはここで「お疲れ様でした」と言いたいのですが、まだ課題が残されているのでした💧

◼︎半角文字に対応していない。

元のテキストに半角英数字などが含まれていた場合、ボックスに収納可能な文字数が変わってきます。全角/半角に対応して文字数をカウントする仕組みを考えなくては。



◼︎ユーザが手動でウィンドゥ幅を変えた時の対処。

PCなどではユーザがウィンドゥの幅を手動で変えることができます。テキストボックスのwidthが相対値で指定されている場合、収納文字数も変わってきます。

ブラウザをこれまた手動で再読み込みすればちゃんとJavaScriptも反映されるのですが、その行動は期待できないでしょう。



これらの課題について、今後も考えていきたいと思います。道のりは険しいけど楽しい 🎵













「ふ」です。

swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。

🐧 twitter 🐧