表示領域からはみ出した文章を省略したい時はtext-overflowが使えますが、1行しか対応していません。
JavaScriptで複数行の場合でも省略できないかと思い、試してみました。
サンプルコード
対応方法として、以下の2案を考えました。
- 表示領域の高さから行数を調べる
- 各文字のoffset().topから調べる
今回は2番目の「各文字のoffset().topから調べる」方法で実装してみます。
HTML
data-omitで省略した行数を指定するようにします。
<p>■2行</p> <p data-omit="2">各種メディアで提供されるサブカルチャーの一つ。「文化芸術振興基本法」ではメディア芸術、関連法律の「コンテンツの創造、保護及び活用の促進に関する法律」ではコンテンツの一つと定義されており、どちらの法律でもアニメと略されてはおらず、アニメーションと正式表記されている。別定義として、多角的芸術分類観点において、美術(映像を含まない)、映像、音楽、文学、芸能の総合芸術とされるときもある。テレビ放送用の1話30分枠の連続作品(詳細はテレビアニメの標準フォーマットを参照)が主流で、劇場用やDVDなどでの単発作品の比率は低い。取り上げる題材は幅広く、多種多様なものが使用されている(詳細は後述、「Category:アニメのジャンル」も参照)。単に「アニメ」という場合は、セルアニメーション(セルアニメ)のことを指していることが多い。本項では、主に日本で製作された商業用セルアニメーションについて解説する。</p> <hr /> <p>■3行</p> <p data-omit="3">各種メディアで提供されるサブカルチャーの一つ。「文化芸術振興基本法」ではメディア芸術、関連法律の「コンテンツの創造、保護及び活用の促進に関する法律」ではコンテンツの一つと定義されており、どちらの法律でもアニメと略されてはおらず、アニメーションと正式表記されている。別定義として、多角的芸術分類観点において、美術(映像を含まない)、映像、音楽、文学、芸能の総合芸術とされるときもある。テレビ放送用の1話30分枠の連続作品(詳細はテレビアニメの標準フォーマットを参照)が主流で、劇場用やDVDなどでの単発作品の比率は低い。取り上げる題材は幅広く、多種多様なものが使用されている(詳細は後述、「Category:アニメのジャンル」も参照)。単に「アニメ」という場合は、セルアニメーション(セルアニメ)のことを指していることが多い。本項では、主に日本で製作された商業用セルアニメーションについて解説する。</p> <hr /> <p>■4行</p> <p data-omit="4">各種メディアで提供されるサブカルチャーの一つ。「文化芸術振興基本法」ではメディア芸術、関連法律の「コンテンツの創造、保護及び活用の促進に関する法律」ではコンテンツの一つと定義されており、どちらの法律でもアニメと略されてはおらず、アニメーションと正式表記されている。別定義として、多角的芸術分類観点において、美術(映像を含まない)、映像、音楽、文学、芸能の総合芸術とされるときもある。テレビ放送用の1話30分枠の連続作品(詳細はテレビアニメの標準フォーマットを参照)が主流で、劇場用やDVDなどでの単発作品の比率は低い。取り上げる題材は幅広く、多種多様なものが使用されている(詳細は後述、「Category:アニメのジャンル」も参照)。単に「アニメ」という場合は、セルアニメーション(セルアニメ)のことを指していることが多い。本項では、主に日本で製作された商業用セルアニメーションについて解説する。</p> <hr />
JavaScript
1文字ずつspanで括って、省略時は非表示にします。
$(function() { var omitMark = '…'; // 省略に使うマーク(1文字でない場合はコードの修正が必要) // 省略したい要素のテキストを加工 for (var i = 0; i < $('[data-omit]').length; i++) { stringSplit($('[data-omit]').eq(i)); } // 1文字ずつspanで括る関数 function stringSplit(element) { var splitArr = element.text().split(''); var joinString = ''; for (var i = 0; i < splitArr.length; i++) { joinString += '<span>' + splitArr[i] + '</span>'; } joinString += '<span class="omit-mark">…</span>'; element.html(joinString); element.children('.omit-mark').hide(); } // 省略チェック for (var i = 0; i < $('[data-omit]').length; i++) { omitCheck($('[data-omit]').eq(i)); } var resizeTimer = null; $(window).on('resize', function() { clearTimeout(resizeTimer); resizeTimer = setTimeout(function() { for (var i = 0; i < $('[data-omit]').length; i++) { omitCheck($('[data-omit]').eq(i)); } }, 200); }); // 省略チェックの関数 function omitCheck(element) { var omitLine = element.data('omit'); var thisSpan = element.children('span'); var lineTop = thisSpan.eq(0).offset().top; // 一行目の文字位置取得 var lineCount = 0; // 現在の行数 var omitCount; // 何文字目で省略するか // data-omitの値が0以下の場合は何もしない if(omitLine <= 0) { return; } // 非表示にしている文字をいったん表示して、何文字目からを非表示にするかを調べる thisSpan.show(); for (var i = 0; i < thisSpan.length - 1; i++) { if(thisSpan.eq(i).offset().top > lineTop) { lineTop = thisSpan.eq(i).offset().top; lineCount++; } // 省略行まで来たとき if(lineCount >= omitLine) { omitCount = i - 2; break; } // 指定行数内に収まりそうなときは省略マーク非表示 if(i >= thisSpan.length - 2) { element.children('.omit-mark').hide(); return; } } // 該当する文字を非表示にする for (var i = omitCount; i < thisSpan.length - 1; i++) { thisSpan.eq(i).hide(); } } });
注意点として、省略する要素内のテキストを1文字ずつspanで括るので、要素内はプレーンなテキスト(spanタグなどを使っていない)である必要があります。
あとは、offset().topで各文字の位置を調べるようにしているので、一部だけ文字サイズを変更していたり、positionなどで位置を調整しているとうまくいかない可能性が高いです。
コメントが承認されるまで時間がかかります。