事象発生日:2017-09-24
記事公開日:2017-09-25
アクセス数:8109
このブログの記事一覧ページでは,記事のアブストラクトをタイトル下に2行分表示している.
記事へのリンクのタイルの横幅がブラウザの画面幅にあわせて変わるようになっているので,アブストラクトの文字数もそれに応じて増減させたいと考えた.
この機能を実装するためにいろいろ調べた結果などをまとめておく.
トップ画像の出典はこちら.
下図のように,コンテンツの幅に応じてその中の文字数を変化させたい.
無理やりJavaScriptで実装した.
$(function() { // texts に表示すべきテキストが与えられている. SetTexts(texts); $(window).on('resize', function() { SetTexts(texts); }) }); function SetTexts(texts) { if (texts.length == 0) { return; } var pWidth = $('#contents .article div.right p.text').width(); // 全角55文字 660px var letterPerPx = 55.0 / 660.0; var numOfLetter = Math.floor(pWidth * letterPerPx * 2) - 2; if (numOfLetter < 0) { numOfLetter = 0; } $('#contents .article div.right p.text').each(function(i) { $(this).text(texts[i].substr(0,numOfLetter) + "..."); }); }
この実装方法の問題点は,
基準文字数を手動で与えているため,環境依存の影響を受ける.具体的には表示フォントが変化すると,2行に収まらなくなる可能性が否定できない. | |
全角文字を基準としているため,半角文字が入ると文字幅が想定より小さくなる. |
ことである.
に,全角文字を2,半角文字を1文字としてカウントするJavaScriptが紹介されている.
文字数をカウントする関数を下に抜粋する.
function strLength(strSrc){ len = 0; strSrc = escape(strSrc); for(i = 0; i < strSrc.length; i++, len++){ if(strSrc.charAt(i) == "%"){ if(strSrc.charAt(++i) == "u"){ i += 3; len++; } i++; } } return len; }
文字列をエンコードし,%u
があるかで全角半角を判断してる.
とても良いアイデアに見えるが,escape()
関数に問題がある.
などのリファレンスを見るとわかるのだが,escape()
関数は現在非推奨であるのだ.
また,全角半角を区別して文字数をカウントできたとしても問題が残る.
それはプロポーショナルフォントである.
一般的な描画用の英字などの半角文字はほぼプロポーショナルフォントだ.
“l”と“m”では,文字幅がかなり違ってしまう.
結局は“文字数”ではなく,“文字幅”を取得する方法が必要となりそうである.
しかし,text-overflow
を使う方法は複数行に対応していないし,
-webkit-line-clamp
を使う方法はWebkit系列のブラウザにしか使えない.
ではどのブラウザにも使用できる方法として,before
とafter
の2つの擬似要素を使う方法を結論として提示しているが,今回のケースのように常に文字があふれるわけではない場合には使用できない.
というわけで,ナイスな方法を知っている人がいましたら,ぜひ教えて下さい.
名前
Email (※公開されることはありません)
コメント