JavaScript で文字をトリミングする(改善版)

JavaScript で文字をトリミングする(改善版)

Posted at December 7,2006 1:55 AM
Tag:[JavaScript]

JavaScript で文字をトリミングするJavaScript を用いてエントリータイトル等の文字をトリミング(指定した文字数だけ表示する)するカスタマイズです。前回の「JavaScript で文字をトリミングする」は文字数だけでトリミングしたものですが、今回の改善版はバイト数で計算します。全角はそのまま1文字として数え、半角英数は2文字(2バイト)を1文字としてカウントします。

左のスクリーンショットが5文字でトリミングしたサンプルです。上は全角のみなので5文字でトリミングし、下は半角を含むので計7文字でトリミングしています。

さらにスクリプトを修正すれば、特定の半角文字("M"とか"W"のような幅の広い文字)を全角として数えることも可能と思われます。完璧に横幅を揃えることはできませんが、かなり精度の良いトリミングができると思います。

今回も「id 属性名」と「要素名+ class 属性名」で指定したタグの中に記述された文字列をトリミングする、JavaScript を書いてみました。

Windows + IE6/Firefox 2 で実験した限りでは、全角・半角いずれも1文字で計算してトリミングしてくれるようですが、コードに不具合等ありましたらお知らせください。

1.スクリプトの追加

次のリストを </head> の直前に追加します。外部ファイルにしても構いません。

<script type="text/javascript">
var rest = '...';
function cutStringById(id, size) {
  var str = document.getElementById(id).innerHTML;
  if(str.length > size){
    document.getElementById(id).innerHTML = str.substring(0, size) + rest;
  }
}
 
function cutStringByTagNameAndClassName(tagName, className, size) {
  var elements = document.getElementsByTagName(tagName);
  for (i=0; i < elements.length; i++) {
    if (elements[i].className == className) {
      var str = elements[i].innerHTML;
      elements[i].innerHTML = trim(str,size);
    }
  }
}
 
function cutStringByIdAndTagName(id, tagName, size) {
  var element = document.getElementById(id);
  var elements = element.getElementsByTagName(tagName);
  for (i=0; i < elements.length; i++) {
    var str = elements[i].innerHTML;
    if(str.length > size){
      elements[i].innerHTML = trim(str,size);
    }
  }
}
 
function cutStringByClassNameAndTagName(className, tagName, size) {
  var elements = document.getElementsByTagName(tagName);
  for (i=0; i < elements.length; i++) {
    if (elements[i].parentNode.className == className) {
      var str = elements[i].innerHTML;
      elements[i].innerHTML = trim(str,size);
    }
  }
}
 
function trim(str, size) {
  if(str.length > size){
    var cutstring = str.substring(0, size);
    var byte = countByte(cutstring);
    var tmp = "";
    if (byte < size*2) {
       for(k=0; k < (size*2-byte)*2; k++){
         tmp = str.substring(0,size + k);
         if (countByte(tmp) >= size*2) {
           break;
         }
       }
    }
    if(tmp){
      return tmp + rest;
    } else {
      return str.substring(0, size) + rest;
    }
  } else {
    return str;
  }
}
 
function countByte(str) {
  var byte = 0;
  for (j=0; j < str.length; j++) {
    str.charCodeAt(j) < 0x100 ? byte++ : byte += 2;
  }
  return byte;
}
</script>

2.スクリプトを起動する

スクリプトを起動するため、2.1~2.4のいずれかの script 要素を 、トリミングしたい文字列の直後、または </body> の直前に追加します。

2.1 要素名+ class 属性名で指定

<script type="text/javascript">
cutStringByTagNameAndClassName('[要素名]', '[class 属性名]', トリミングサイズ);
</script>

2.2 id 属性名で指定

<script type="text/javascript">
cutStringById('[id 属性名]', トリミングサイズ);
</script>

2.3 id 属性名+ 要素名で指定

<script type="text/javascript">
cutStringByIdAndTagName('[id 属性名]', '[要素名]', トリミングサイズ);
</script>

2.4 親要素の class 属性名+ 要素名で指定

<script type="text/javascript">
cutStringByClassNameAndTagName('[親要素の class 属性名]', '[要素名]', トリミングサイズ);
</script>

具体的な起動方法は3項をご覧ください。

3.サンプル

3.1 要素名+ class 属性名で指定

次の(X)HTMLマークアップ、

<a href="http://domain.com/" class="hoge">文字をトリミングする</a>

の「文字をトリミングする」の文字を先頭から 5 文字だけ表示(「文字をトリ...」にする)する場合は、2.1のリストを利用し、赤色部分を、

cutStringByTagNameAndClassName('a', 'hoge', 5);

とします。

3.2 id 属性名で指定

次の(X)HTMLマークアップ、

<p id="hoge">文字をトリミングする</p>

の「文字をトリミングする」の文字を先頭から 5 文字だけ表示(「文字をトリ...」にする)する場合は、2.2のリストを用い、その赤色部分を

cutStringById('hoge', 5);

とします。

3.3 id 属性名+ 要素名で指定

次の(X)HTMLマークアップ、

<div id="hoge"><a href="http://domain.com/">文字をトリミングする</a></div>

の「文字をトリミングする」の文字を先頭から 5 文字だけ表示(「文字をトリ...」にする)する場合は、2.3のリストを利用し、赤色部分を、

cutStringByIdAndTagName('hoge', 'a', 5);

とします。

3.4 親要素の class 属性名+ 要素名で指定

次の(X)HTMLマークアップ、

<div class="hoge"><a href="http://domain.com/">文字をトリミングする</a></div>

の「文字をトリミングする」の文字を先頭から 5 文字だけ表示(「文字をトリ...」にする)する場合は、2.4のリストを利用し、赤色部分を、

cutStringByClassNameAndTagName('hoge', 'a', 5);

とします。

4.トリミング後の追加文字列を変更する

トリミング後の追加文字列を変更するには、冒頭のリスト2 行目を他の文字に変更してください。何も表示させたくない場合は赤色部分を削除してください。

var rest = '...';

5.特定の半角文字のバイト数を変更する

1項のスクリプトに青色のような行を追加します(間違ってたらすいません)。赤色部分は "0xXX" という、16進数を設定します。

function countByte(str) {
  var byte = 0;
  for (j=0; j < str.length; j++) {
    str.charCodeAt(j) < 0x100 ? byte++ : byte += 2;
    if(str.charCodeAt(j) == [該当文字の16進数]) byte++;
  }
  return byte;
}

charCodeAt は指定した文字の Unicode を返却する関数です。JavaScript 1.2 と 1.3 で振る舞いが異なるようです。

2006.12.28
id 属性名+要素名で検索できるコードを、スクリプトおよびリスト2.3項に追加しました。

2007.02.15
トリミング文字列が短い場合に正常に表示されない不具合を修正しました。

2008.08.03
cutStringByClassNameAndTagName を追加しました。

関連記事
zenback
人気エントリー
トラックバックURL


トラックバック

サイドバーの文字数を制限する from OKANOWEB.NET
小粋空間さんのJavaScript で文字をトリミングするを参考に、私のブログの... [続きを読む]

Tracked on March 29, 2007 5:29 PM
コメント

以前質問したことを覚えて下すってたんですね。
ありがとうごさいます。
募金したいんですけどやり方がわからず、四苦八苦してます。

できればやり方を教えて頂けるとありがたいです。

[1] Posted by きくみ : December 27, 2006 12:21 AM

>きくみさん
こんにちは。
ご連絡ありがとうございました。
募金(ドネーションですね)の方法につきましては別途エントリーしたいと思います。
なお、本カスタマイズはHTMLタグの構造によってスクリプトを修正する必要があります。具体的にトリミングしたい部分を言って頂ければ、それに合うスクリプトを作成致します。
それではよろしくお願い致します。

[2] Posted by yujiro : December 27, 2006 12:36 PM

サイドバーの新着記事のタイトル(記事タイトル)を11?12文字(全角)で表示して、その後を
”。。。”としたく思ってます。

募金金額500円くらいしか出せないのですがいいですか?

[3] Posted by きくみ : December 27, 2006 11:58 PM

>きくみさん
こんにちは。
とりあえずご要望の機能をリスト1.1 とリスト2.3 に追加しましたのでお試しください。
リスト2.3 は下記のようにするとうまくできると思います。

<script type="text/javascript">
<!--
cutStringByIdAndTagName('最新記事list', 'a', 17);
//-->
</script>

ご寄付の有無や金額はご自由です。
それではよろしくお願い致します。

[4] Posted by yujiro : December 28, 2006 7:21 PM

指定した文字数以下のものが検出されるとその文字列がundefinedとなってしまいますがどのようにすればうまく表示されますでしょうか?

[5] Posted by oss : February 14, 2007 3:00 AM

>ossさん
こんにちは。
ご質問の件ですが、リスト1.1 を修正致しましたのでご確認頂ければ幸いです。
それではよろしくお願い致します。

[6] Posted by yujiro : February 15, 2007 3:03 PM

はじめまして。
おォっと思い使わせていただこうとテストしてみましたが。
指定しているフォントサイズが反映されなくなりました。
以上です。

[7] Posted by りか : February 20, 2008 5:36 PM

>りかさん
こんにちは。
情報ありがとうございました。
ではでは!

[8] Posted by yujiro logo : February 21, 2008 12:05 AM

こんばんは。
フォントサイズの件ですが、FireFox2では指定した文字サイズで表示されるのですが、IE7だと最大サイズになってしまいます。
では、ご報告まで

by りか

[9] Posted by りか : February 21, 2008 2:35 AM

>りかさん
こんばんは。
たびたびのご連絡、ありがとうございました!

[10] Posted by yujiro logo : February 21, 2008 11:11 PM

feedburnerのバズブースト機能で出力されるhtmlのheadline(各記事の件名)をトリミングしようとしているのですが、

↓こんな構造のせいで使えません。(泣)
<span class="headline"><a href="#">First item headline here</a></span>

このjavascriptをたとえば「特定の範囲のaタグ全て」に適用したり
することができれば解決すると思ったのですが、可能でしょうか。

feedburnerの方に機能としてあれば一番いいのですが。^^;

[11] Posted by miyamoto : July 29, 2008 11:59 AM

>miyamotoさん
こんばんは。
ご質問の件ですが、ご要望のマークアップに対応できるよう、スクリプトを修正しましたのでお試しください。冒頭のスクリプトをコピーして、2.4項、3.4項の設定を行ってください。
それではよろしくお願い致します。

[12] Posted by yujiro logo : August 3, 2008 10:43 PM
コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)