229

JavaScript で文字列を切り捨て、末尾に省略記号を付けるための、より洗練されたソリューション/ライブラリを持っている人はいますか?

if (string.length > 25) {
  string = string.substring(0, 24) + "...";
}
4

25 に答える 25

442

基本的に、指定された文字列の長さを確認します。指定された長さよりも長い場合は、n長さnsubstrまたはslice)にクリップし、クリップされた文字列にhtmlエンティティ…(…)を追加します。

そのような方法は次のようになります

function truncate(str, n){
  return (str.length > n) ? str.substr(0, n-1) + '…' : str;
};

「より洗練された」とは、文字列の最後の単語境界で切り捨てることを意味する場合は、追加のチェックが必要です。最初に文字列を目的の長さにクリップし、次にその結果を最後の単語の境界にクリップします

function truncate( str, n, useWordBoundary ){
  if (str.length <= n) { return str; }
  const subString = str.substr(0, n-1); // the original check
  return (useWordBoundary 
    ? subString.substr(0, subString.lastIndexOf(" ")) 
    : subString) + "&hellip;";
};

String関数を使用してネイティブプロトタイプを拡張できます。その場合、strパラメータを削除strし、関数内を次のように置き換える必要がありますthis

String.prototype.truncate = String.prototype.truncate || 
function ( n, useWordBoundary ){
  if (this.length <= n) { return this; }
  const subString = this.substr(0, n-1); // the original check
  return (useWordBoundary 
    ? subString.substr(0, subString.lastIndexOf(" ")) 
    : subString) + "&hellip;";
};

より独断的な開発者はそれについてあなたを強く叱責するかもしれません(「あなたが所有していないオブジェクトを変更しないでください」。私は気にしません)。

プロトタイプを拡張しないアプローチStringは、提供する(長い)文字列とそれを切り捨てるための前述のメソッドを含む独自のヘルパーオブジェクトを作成することです。それが以下のスニペットが行うことです。

const LongstringHelper = str => {
  const sliceBoundary = str => str.substr(0, str.lastIndexOf(" "));
  const truncate = (n, useWordBoundary) => 
        str.length <= n ? str : `${ useWordBoundary 
          ? sliceBoundary(str.slice(0, n - 1))
          : str.substr(0, n - 1)}&hellip;`;
  return { full: str,  truncate };
}; 
const longStr = LongstringHelper(`Lorem ipsum dolor sit amet, consectetur 
adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore 
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation 
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute 
irure dolor in reprehenderit in voluptate velit esse cillum dolore 
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 
proident, sunt in culpa qui officia deserunt mollit anim id est laborum`);

const plain = document.querySelector("#resultTruncatedPlain");
const lastWord = document.querySelector("#resultTruncatedBoundary");
plain.innerHTML = 
  longStr.truncate(+plain.dataset.truncateat, !!+plain.dataset.onword);
lastWord.innerHTML = 
  longStr.truncate(+lastWord.dataset.truncateat, !!+lastWord.dataset.onword);
document.querySelector("#resultFull").innerHTML = longStr.full;
body {
  font: normal 12px/15px verdana, arial;
}

p {
  width: 450px;
}

#resultTruncatedPlain:before {
  content: 'Truncated (plain) n='attr(data-truncateat)': ';
  color: green;
}

#resultTruncatedBoundary:before {
  content: 'Truncated (last whole word) n='attr(data-truncateat)': ';
  color: green;
}

#resultFull:before {
  content: 'Full: ';
  color: green;
}
<p id="resultTruncatedPlain" data-truncateat="120" data-onword="0"></p>
<p id="resultTruncatedBoundary" data-truncateat="120" data-onword="1"></p>
<p id="resultFull"></p>

最後に、cssは、HTMLノードの長い文字列を切り捨てるためにのみ使用できます。それはあなたにあまり制御を与えませんが、実行可能な解決策かもしれません。

body {
  font: normal 12px/15px verdana, arial;
  margin: 2rem;
}

.truncate {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 30vw;
}

.truncate:before{
  content: attr(data-longstring);
}

.truncate:hover::before {
  content: attr(data-longstring);
  width: auto;
  height: auto;
  overflow: initial;
  text-overflow: initial;
  white-space: initial;
  background-color: white;
  display: inline-block;
}
<div class="truncate" data-longstring="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."></div>

于 2009-07-29T10:56:50.903 に答える
71

これは Firefox でのみ行う必要があることに注意してください。

他のすべてのブラウザーは CSS ソリューションをサポートしています (サポート表を参照)。

p {
    white-space: nowrap;
    width: 100%;                   /* IE6 needs any width */
    overflow: hidden;              /* "overflow" value must be different from  visible"*/ 
    -o-text-overflow: ellipsis;    /* Opera < 11*/
    text-overflow:    ellipsis;    /* IE, Safari (WebKit), Opera >= 11, FF > 6 */
}

皮肉なことに、Mozilla MDC からそのコード スニペットを入手しました。

于 2009-07-29T12:38:15.273 に答える
33

CSS ではなく JavaScript でこれを行いたいと考える正当な理由があります。

JavaScript で 8 文字 (省略記号を含む) に切り詰めるには:

short = long.replace(/(.{7})..+/, "$1&hellip;");

また

short = long.replace(/(.{7})..+/, "$1…");
于 2016-10-10T21:50:34.463 に答える
31

いずれかのlodashのトランケートを使用してください

_.truncate('hi-diddly-ho there, neighborino');
// → 'hi-diddly-ho there, neighbo…'

またはunderscore.string の truncate

_('Hello world').truncate(5); => 'Hello...'
于 2016-04-08T13:37:31.313 に答える
8

最新のブラウザはすべて、テキスト行が使用可能な幅を超えた場合に省略記号を自動的に追加する単純な CSS ソリューションをサポートするようになりました。

p {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

(これを有効にするには、要素の幅を何らかの方法で制限する必要があることに注意してください。)

https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/に基づきます。

このアプローチは、文字数に基づいて制限されないことに注意してください。複数行のテキストを許可する必要がある場合にも機能しません。

于 2012-03-20T17:42:44.003 に答える
7

他の提案よりもいくつかの改善点がある私のソリューションは次のとおりです。

String.prototype.truncate = function(){
    var re = this.match(/^.{0,25}[\S]*/);
    var l = re[0].length;
    var re = re[0].replace(/\s$/,'');
    if(l < this.length)
        re = re + "&hellip;";
    return re;
}

// "This is a short string".truncate();
"This is a short string"

// "Thisstringismuchlongerthan25characters".truncate();
"Thisstringismuchlongerthan25characters"

// "This string is much longer than 25 characters and has spaces".truncate();
"This string is much longer&hellip;"

これ:

  • 25 文字の後の最初のスペースで切り捨てます
  • JavaScript String オブジェクトを拡張して、任意の文字列で使用 (およびチェーン) できるようにします。
  • 切り捨てによって末尾のスペースが生じる場合、文字列を切り捨てます。
  • 切り捨てられた文字列が 25 文字を超える場合、Unicode の helip エンティティ (省略記号) を追加します
于 2009-07-29T11:37:43.270 に答える
6

最新の Javascript フレームワーク ( JQueryPrototypeなど) のほとんどには、これを処理するユーティリティ関数が String に追加されています。

プロトタイプの例を次に示します。

'Some random text'.truncate(10);
// -> 'Some ra...'

これは、他の誰かに処理/保守してもらいたい機能の 1 つに思えます。より多くのコードを記述するのではなく、フレームワークに処理させます。

于 2009-07-29T11:27:13.250 に答える
2

おそらく、誰かがnullを処理している例を見逃していましたが、nullがあった場合、3つのトップの回答はうまくいきませんでした(確かに、エラー処理と他の何百万ものことは、質問に答える人の責任ではないことを理解していますが、私は既存の関数を、他の人に提供すると思っていた優れた切り捨て省略記号の回答の 1 つと共に使用していました。

例えば

JavaScript:

news.comments

切り捨て関数の使用

news.comments.trunc(20, true);

ただし、news.comments がnullの場合 、これは「壊れる」でしょう。

最後の

checkNull(news.comments).trunc(20, true) 

KooiInc提供の trunc 関数

String.prototype.trunc =
 function (n, useWordBoundary) {
     console.log(this);
     var isTooLong = this.length > n,
         s_ = isTooLong ? this.substr(0, n - 1) : this;
     s_ = (useWordBoundary && isTooLong) ? s_.substr(0, s_.lastIndexOf(' ')) : s_;
     return isTooLong ? s_ + '&hellip;' : s_;
 };

私の単純なヌルチェッカー(文字通りの「ヌル」もチェックします(これは未定義、「」、ヌル、「ヌル」などをキャッチします。)

  function checkNull(val) {
      if (val) {
          if (val === "null") {
              return "";
          } else {
              return val;
          }
      } else {
          return "";
      }
  }
于 2015-12-07T17:31:44.740 に答える
1

Ext.jsを使用している場合は、Ext.util.Format.ellipsis関数を使用できます。

于 2012-07-30T19:50:34.087 に答える
1

簡単なグーグルで私はこれを見つけまし...それはあなたのために働きますか?

/**
 * Truncate a string to the given length, breaking at word boundaries and adding an elipsis
 * @param string str String to be truncated
 * @param integer limit Max length of the string
 * @return string
 */
var truncate = function (str, limit) {
    var bits, i;
    if (STR !== typeof str) {
        return '';
    }
    bits = str.split('');
    if (bits.length > limit) {
        for (i = bits.length - 1; i > -1; --i) {
            if (i > limit) {
                bits.length = i;
            }
            else if (' ' === bits[i]) {
                bits.length = i;
                break;
            }
        }
        bits.push('...');
    }
    return bits.join('');
};
// END: truncate
于 2009-07-29T10:48:46.837 に答える
1

Kooilncのソリューションに賛成しました。本当に素晴らしいコンパクトなソリューションです。対処したい小さなエッジケースが 1 つあります。誰かが何らかの理由で非常に長い文字シーケンスを入力した場合、切り捨てられません:

function truncate(str, n, useWordBoundary) {
    var singular, tooLong = str.length > n;
    useWordBoundary = useWordBoundary || true;

    // Edge case where someone enters a ridiculously long string.
    str = tooLong ? str.substr(0, n-1) : str;

    singular = (str.search(/\s/) === -1) ? true : false;
    if(!singular) {
      str = useWordBoundary && tooLong ? str.substr(0, str.lastIndexOf(' ')) : str;
    }

    return  tooLong ? str + '&hellip;' : str;
}
于 2013-12-11T15:24:11.257 に答える
0

c_harmの答えは私の意見では最高です。使用したい場合はご注意ください

"My string".truncate(n)

リテラルではなく、正規表現オブジェクトコンストラクターを使用する必要があります。\Sまた、変換するときはエスケープする必要があります。

String.prototype.truncate =
    function(n){
        var p  = new RegExp("^.{0," + n + "}[\\S]*", 'g');
        var re = this.match(p);
        var l  = re[0].length;
        var re = re[0].replace(/\s$/,'');

        if (l < this.length) return re + '&hellip;';
    };
于 2013-02-27T09:11:22.397 に答える
0

次のコードを使用

 function trancateTitle (title) {
    var length = 10;
    if (title.length > length) {
       title = title.substring(0, length)+'...';
    }
    return title;
}
于 2014-04-23T14:01:47.753 に答える
0

私は最近これをしなければならず、結局次のようになりました:

/**
 * Truncate a string over a given length and add ellipsis if necessary
 * @param {string} str - string to be truncated
 * @param {integer} limit - max length of the string before truncating
 * @return {string} truncated string
 */
function truncate(str, limit) {
    return (str.length < limit) ? str : str.substring(0, limit).replace(/\w{3}$/gi, '...');
}

私には素晴らしくてきれいに感じます:)

于 2017-01-31T15:26:25.947 に答える