MENU

溶けかけてるうさぎ HP BLOG TOP RECENT ARTICLES POPULAR ARTICLES ABOUT THIS BLOG

CATEGORY

大学 (85) 航空宇宙 (55) 写真 (25) 旅行 (14) 飯・酒 (11) コンピュータ (88) その他 (13)

TAG

ARCHIVE

2018 (92) 2017 (80) 2016 (0)

RECENT

【駅メモ】4年目に突入して,ようやく3000駅突破 【WebRTC】Raspberry Pi搭載ロボットをWebRTCで遠隔操作しようとして失敗した 【航空宇宙】航空宇宙アドベントカレンダー 始まります! 【Perl】YAPC::Tokyo 2019 のチケットを確保しました! 【カメラ】Canonから富士フイルムに乗り換えました

【JavaScript】表示する文字数を横幅に応じて変化させる方法

2017-09-24

このブログの記事一覧ページでは,記事のアブストラクトをタイトル下に2行分表示している.

記事へのリンクのタイルの横幅がブラウザの画面幅にあわせて変わるようになっているので,アブストラクトの文字数もそれに応じて増減させたいと考えた.

この機能を実装するためにいろいろ調べた結果などをまとめておく.

 

トップ画像の出典はこちら

1.実装したい機能

下図のように,コンテンツの幅に応じてその中の文字数を変化させたい.

幅が狭い時
幅が広い時

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) + "...");
	});
}
JavaScript (JQuery) のコード

問題点

この実装方法の問題点は,

基準文字数を手動で与えているため,環境依存の影響を受ける.具体的には表示フォントが変化すると,2行に収まらなくなる可能性が否定できない.
全角文字を基準としているため,半角文字が入ると文字幅が想定より小さくなる.

ことである.

3.JavaScriptで全角半角を区別し文字数をカウントする方法

に,全角文字を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;
}
全角半角を区別して文字数をカウントするJavaScriptコード

文字列をエンコードし,%uがあるかで全角半角を判断してる.

 

とても良いアイデアに見えるが,escape()関数に問題がある.

などのリファレンスを見るとわかるのだが,escape()関数は現在非推奨であるのだ.

 

また,全角半角を区別して文字数をカウントできたとしても問題が残る.

それはプロポーショナルフォントである.

一般的な描画用の英字などの半角文字はほぼプロポーショナルフォントだ.

“l”と“m”では,文字幅がかなり違ってしまう.

 

結局は“文字数”ではなく,“文字幅”を取得する方法が必要となりそうである.

4.CSSで頑張る方法

にCSSのみで頑張る方法が記載されている.

しかし,text-overflowを使う方法は複数行に対応していないし,

-webkit-line-clampを使う方法はWebkit系列のブラウザにしか使えない.

 

ではどのブラウザにも使用できる方法として,beforeafterの2つの擬似要素を使う方法を結論として提示しているが,今回のケースのように常に文字があふれるわけではない場合には使用できない.

5.結論

頭のいい人教えて!

というわけで,ナイスな方法を知っている人がいましたら,ぜひ教えて下さい.

6.出典サイト

Webプログラマー+WebデザイナーなZARU日記. 全角・半角を判別して文字数をカウントするJavaScript. Retrieved September 24, 2017, from http://blog.tofu-kun.org/070627210315.php
MDN web docs. escape(). Retrieved September 24, 2017, from https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/escape
NET BIZ DIV. TECH BLOG. 【複数行にも対応】長過ぎる文字列を省略して末尾を三点リーダー(…)にする方法いろいろ. Retrieved September 24, 2017, from https://tech.recruit-mp.co.jp/front-end/tips-ellipsis/

コメントを投稿

名前

Email (※公開されることはありません)

コメント