Uzun telleri kısaltmanın akıllı yolu


187

JavaScript ile dizeleri kırpmak ve sonuna bir üç nokta koymak için daha sofistike bir çözüm / kütüphane var mı:

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

5
"Daha sofistike" ile ne demek istiyorsun? Sözcük sınırlarını dikkate alan işlevler?
Residuum

2
Ve HTML etiketlerinin ortasında kesilmiyor.
Sz.

Yanıtlar:


366

Esas olarak, verilen dizenin uzunluğunu kontrol edersiniz. Belirli bir uzunluktan daha uzunsa n, uzunluğa n( substrveya slice) …kırpın ve kırpılan dizeye html varlığı (…) ekleyin .

Böyle bir yöntem benziyor

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

Eğer 'daha sofistike' ile bir dizgenin son kelime sınırında kısalmak istiyorsan ekstra bir kontrol gerekir. Önce dizeyi istediğiniz uzunluğa, ardından sonucunu son sözcük sınırına kırpırsınız

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;";
};

Yerel Stringprototipi işlevinizle genişletebilirsiniz . Bu durumda strparametre kaldırılmalı ve strişlev içinde aşağıdakilerle değiştirilmelidir 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;";
};

Daha dogmatik geliştiriciler sizi bu konuda güçlü bir şekilde teslim edebilir ("Sahip olmadığınız nesneleri değiştirmeyin ".

StringPrototipi genişletmeden bir yaklaşım , sağladığınız (uzun) dizeyi ve onu kısaltmak için yukarıda belirtilen yöntemi içeren kendi yardımcı nesnenizi oluşturmaktır. Aşağıdaki pasaj bunu yapar.

Son olarak, css komutunu yalnızca HTML düğümlerindeki uzun dizeleri kısaltmak için kullanabilirsiniz. Size daha az kontrol sağlar, ancak uygulanabilir bir çözüm olabilir.


5
Örneğin, dize 500 karakterden daha uzunsa, "sert" ve "yumuşak" sınırlara sahip olmayı da düşünmelisiniz, 400'e kısaltın. Kullanıcı metnin tamamını görmek istediğinde ve bir bağlantıyı tıkladığında bu yararlı olabilir onun için. Sonuç olarak, sadece 1 veya 2 karakter daha yüklerseniz, gerçekten çirkin görünecektir.
Maxim Sloyko

2
İkinci parametre substrbir uzunluktur, bu nedenle onu substr(0,n)ilk nkarakterlerle sınırlamak gerekir .
JohnnyHK

10
Sahip olmadığınız nesneleri değiştirmeyin. nczonline.net/blog/2010/03/02/…
Charlie Kilian

5
Dikkate alacağınız bir şey , kod örneğinizdeki &hellip;gerçek elips ( ...) ile değiştirmektir . Bunu API'larla etkileşime girmek için kullanmaya çalışıyorsanız, orada HTML olmayan varlığı isteyeceksiniz.
AlbertEngelB

1
@RuneJeppesen haklısın. Yöntemleri düzeltti. Savunmam için: cevap 7 yıl öncesine dayanıyor;)
KooiInc

62

Bunun yalnızca Firefox için yapılması gerektiğini unutmayın.

Diğer tüm tarayıcılar bir CSS çözümünü destekler ( destek tablosuna bakın ):

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 */
}

İronik olan, bu kod snippet'ini Mozilla MDC'den aldım.


1
mattsnider.com/css/css-string-truncation-with-ellipsis , FF ile de çalışmasını sağlar.
Neal

Vay be bu mobil Safari için mükemmel bir çözüm. Teşekkür ederim!
samvermette

9
Çok iyi CSS yaklaşımı. Bunun yalnızca tek bir metin satırıyla (amaçlandığı gibi white-space: nowrap;) çalıştığı bir not olabilir . Birden fazla satır söz konusu olduğunda, JavaScript ile sıkışıp kalırsınız.
insertusernameburada

Ayrıca yalnızca tüm eleman için çalışır. Bir dizenin bir kısmını kısaltmak istiyorsanız, bir yayılma alanı veya başka bir html öğesinde kısaltmak istediğiniz biti sarmadan, bu işe yaramaz, örneğin:Your picture ('some very long picture filename truncated...') has been uploaded.
Chris

1
OP özellikle javascript çözümü istedi
vsync

25

Kullanıcıların bunu JavaScript'te CSS yerine yapmak isteyebileceklerinin geçerli nedenleri vardır.

JavaScript'te 8 karaktere (üç nokta dahil) kısaltmak için:

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

veya

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

1
Üç nokta sayılırsa, bu 9 karakter olacaktır. .replace(/^(.{7}).{2,}/, "$1…");
Kesmeden

longve shorteski ECMAScript spesifikasyonlarına (ECMAScript 1 ila 3) gelecekteki anahtar kelimeler olarak ayrılmıştır. Bkz MDN: Gelecek eski standartlarda anahtar kelimeleri saklıdır
Ricardo


9
('long text to be truncated').replace(/(.{250})..+/, "$1…");

Her nasılsa yukarıdaki kod vuejs app yapıştırılan veya yazılı metin bir tür için çalışma değildi. Bu yüzden kesik kesik kullandım ve şimdi iyi çalışıyor.

_.truncate('long text to be truncated', { 'length': 250, 'separator': ' '});

güzel modern cevap!
ykonda

Metnin ne olduğunu merak ediyorum. Latin olmayan karakterler mi kullanıyordu?
Adam Leggett

Bu sadece bir lorem
ipsumuydu

7

İşte diğer öneriler üzerinde birkaç iyileştirme olan benim çözüm:

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;"

O:

  • 25 karakterden sonra ilk boşlukta kısalır
  • JavaScript String nesnesini genişletir, böylece herhangi bir dizede kullanılabilir (ve bu dizine zincirlenebilir).
  • Kesme, sondaki boşlukla sonuçlanırsa dizeyi keser;
  • Kesilen dize 25 karakterden uzunsa unicode hellip varlığını (üç nokta) ekler

7

Bulduğum en iyi fonksiyon. Metin üç noktaya kredi .

function textEllipsis(str, maxLength, { side = "end", ellipsis = "..." } = {}) {
  if (str.length > maxLength) {
    switch (side) {
      case "start":
        return ellipsis + str.slice(-(maxLength - ellipsis.length));
      case "end":
      default:
        return str.slice(0, maxLength - ellipsis.length) + ellipsis;
    }
  }
  return str;
}

Örnekler :

var short = textEllipsis('a very long text', 10);
console.log(short);
// "a very ..."

var short = textEllipsis('a very long text', 10, { side: 'start' });
console.log(short);
// "...ng text"

var short = textEllipsis('a very long text', 10, { textEllipsis: ' END' });
console.log(short);
// "a very END"

5

Tüm modern tarayıcılar artık bir metin satırı mevcut genişliği aşarsa otomatik olarak üç nokta eklemek için basit bir CSS çözümünü desteklemektedir:

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

(Bunun, herhangi bir etkisi olması için öğenin genişliğinin bir şekilde sınırlandırılmasını gerektirdiğini unutmayın.)

Göre https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/ .

Yaklaşımın olmadığını belirtmek gerekir değil karakterlerin sayısına bağlı sınırlar. Ayrıca gelmez değil metnin birden fazla satır izin vermek gerekirse çalışır.


2
Bu sadece tek satırlık cümleler için kullanışlıdır, CSS ile çok satırlı bir örnek yapmanın (şimdiye kadar bildiğim kadar) yolu yoktur.
Hooman Askari

Bunu şans eseri sol yerine üç nokta yerine sağ tarafta yapmak için bir yol var mı?
GreenAsJade

1
@GreenAsJade Bunu text-direction: rtlve ile başarabileceğine inanıyorum text-align: left. Bkz. Davidwalsh.name/css-ellipsis-left
Sean the Bean

4

Çoğu modern Javascript çerçevesi ( JQuery , Prototype , vb .) Bunu işleyen String'e yapıştırılmış bir yardımcı program fonksiyonuna sahiptir.

Prototipte bir örnek:

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

Bu, başka birinin başa çıkmasını / bakımını yapmasını istediğiniz işlevlerden biri gibi görünüyor. Daha fazla kod yazmak yerine, çerçevenin üstesinden gelmesine izin verirdim.


8
Ben jQuery bunun için bir şey olduğunu sanmıyorum.
alex

2
. Underscore.js yapar - _ ( 'Merhaba dünya') kesiği (5) => 'Merhaba ...' _ ( 'Merhaba') kesiği (10) => 'Merhaba'.
JayCrossler

3
Saf Alt Çizgi de görünmüyor truncate()- alt çizgi gibi bir uzantıya ihtiyacınız olabilir .
martin

2
Bu kesinlikle doğru cevap. Alt çizgiyi bilmiyorum, ama _.trunctam olarak bunu yapan lodash var .
leftclickben

2
Doğru cevabın lodash.trunc veya underscore.string.truncate kullanmak olduğunu düşünüyorum.
ooolala

2

Belki birisinin null'ları ele aldığı bir örneği kaçırdım, ancak null'larım olduğunda 3 TOP yanıtı benim için işe yaramadı (Elbette hata işlemenin olduğunu ve milyon başka şeyin soruyu cevaplayan kişinin sorumluluğu DEĞİL olduğunu anlıyorum, ancak Başkaları için sağlayacağımı düşündüğüm mükemmel kesilme üç nokta cevaplarından biri ile birlikte mevcut bir işlevi kullanmıştım.

Örneğin

javascript:

news.comments

kesme fonksiyonunu kullanma

news.comments.trunc(20, true);

Ancak, news.comments boş olması bu "kırmak" olacaktır

final

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

trunk işlevi KooiInc'in izniyle

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_;
 };

Benim basit null denetleyicisi (gerçek "null" şey de denetler (bu tanımsız, "", null, "null", vb yakalar)

  function checkNull(val) {
      if (val) {
          if (val === "null") {
              return "";
          } else {
              return val;
          }
      } else {
          return "";
      }
  }

İşte değiştirilmiş bir sürüm - prototip kullanımını önler, işlevde boş kontrol içerir ve bazı test / demo kullanımı vardır. codepen.io/mahemoff/pen/LGEdzy
mahemoff

Prototipin sorunlu olduğunu düşünüyor musunuz? Sadece merak ediyorum
Tom Stickel

Benim ayrı null denetimi işlevi nedeni aslında boş olup olmadığını kontrol edecektir, NaN, boş bir dize ( ""), 0, yanlış ve "boş" Ama fx gibi genel olarak ben tanımsız
Tom Stickel

1
Evet, bu bir fikir ve kullanım bağlamıdır, ancak aynı kütüphaneyi geçersiz kılabileceği için diğer kütüphanelerle çalışırken prototip çirkinleşir. (Veya nadir durumlarda, aynı ada sahip bir işlev daha sonra standart dil özelliği olarak tanıtılabilir.)
mahemoff

Evet, sana katılıyorum
Tom Stickel

2

Bazen dosya adları numaralandırılır; burada dizin başında veya sonunda olabilir. Bu yüzden ipin merkezinden kısaltmak istedim:

function stringTruncateFromCenter(str, maxLength) {
    const midChar = "…";      // character to insert into the center of the result
    var left, right;

    if (str.length <= maxLength) return str;

    // length of beginning part      
    left = Math.ceil(maxLength / 2);

    // start index of ending part   
    right = str.length - Math.floor(maxLength / 2) + 1;   

    return str.substr(0, left) + midChar + str.substring(right);
}

UTF-8'de 1 bayttan fazla dolgu karakteri kullandığımı unutmayın.



1

Kooilnc'nin çözümünü iptal ettim. Gerçekten güzel kompakt çözüm. Ele almak istediğim küçük bir kenarlık var. Birisi herhangi bir nedenle gerçekten uzun bir karakter dizisine girerse, kesilmez:

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;
}

1

Hızlı bir Google ile bunu buldum ... Bu sizin için uygun mu?

/**
 * 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

1

Metin taşması: üç nokta, ihtiyacınız olan özelliktir. Bu ve bir taşma ile: belirli bir genişlikle gizlenmiş, sonunda üç periyot etkisini alacak olan her şey ... Boşluk eklemeyi unutmayın: nowrap veya metin birden çok satıra konur.

.wrap{
  text-overflow: ellipsis
  white-space: nowrap;
  overflow: hidden;
  width:"your desired width";
}
<p class="wrap">The string to be cut</p>

1
Kısalık kabul edilebilir, ancak daha kapsamlı açıklamalar daha iyidir.
Armali

mwilcox ve Bean the Sean zaten bu çözümü yayınladılar.
Andrew Myers

1
Sadece tek satırlık metinler için kullanılabilir
Vally Pepyako

Metin taşması: üç nokta mükemmel!
zardilior

0

c_harm'ın cevabı bence en iyisidir. Kullanmak istiyorsanız lütfen unutmayın

"My string".truncate(n)

değişmez değer yerine regexp nesne yapıcısı kullanmanız gerekir. Ayrıca \Sdönüştürürken kaçmak zorunda kalacaksınız .

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;';
    };

Herkes yorum ve uygun değişken adlandırma duydunuz mu?
bisiklet

@bisiklet kodu yukarıdaki başka bir cevaptan kopyalanır ve değiştirilir, çok kaba ve sinsi olmaya gerek yoktur.
Matt Fletcher

0

Aşağıdaki kodu kullanın

 function trancateTitle (title) {
    var length = 10;
    if (title.length > length) {
       title = title.substring(0, length)+'...';
    }
    return title;
}

0

Kooilnc'nin çözümünü düzeltme:

String.prototype.trunc = String.prototype.trunc ||
  function(n){
      return this.length>n ? this.substr(0,n-1)+'&hellip;' : this.toString();
  };

Bu, kesilmesi gerekmiyorsa String nesnesi yerine dize değerini döndürür.


Bu soruya bir cevap vermez. Bir yazarın eleştirisini yapmak veya açıklama istemek için yazılarının altına bir yorum bırakın - her zaman kendi yayınlarınıza yorum yapabilirsiniz ve yeterli bir üne sahip olduğunuzda herhangi bir yazı hakkında yorum yapabilirsiniz .
Spencer Wieczorek

Ah şimdi ayrımı görüyorum. Referanslar için teşekkürler. @Kooilnc'nin göreceği ümidiyle bir yorum bırakmak ve kabul ettiyse, ancak kabul edilen cevabı olmasa da muhtemelen kabul edilen cevabı düzenlemek istedim.
qwales1

0

Son zamanlarda bunu yapmak zorunda kaldı ve ile sona erdi:

/**
 * 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, '...');
}

Bana güzel ve temiz geliyor :)


1
Bu, sonuçta elde edilen dizgiyi 3 karakterden daha uzun sürebilir.
Hauke

0

Ben .slice () kullanmayı seviyorum İlk argüman başlangıç ​​dizin ve ikincisi bitiş endeksidir. Aradaki her şey geri döndüğünüz şey.

var long = "hello there! Good day to ya."
// hello there! Good day to ya.

var short  = long.slice(0, 5)
// hello

0

Akıllı Bir Yerde: D

//My Huge Huge String
    let tooHugeToHandle = `It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).`
    
//Trim Max Length
 const maxValue = 50
// The barber.
 const TrimMyString = (string, maxLength, start = 0) => {
//Note - `start` is if I want to start after some point of the string
    	if (string.length > maxLength) {
    	let trimmedString = string.substr(start, maxLength)
    	 return (
    	   trimmedString.substr(
    	   start,
    	   Math.min(trimmedString.length,   trimmedString.lastIndexOf(' '))
           ) + ' ...'
         )
       }
    return string
}

console.log(TrimMyString(tooHugeToHandle, maxValue))


-1

Bu işlev, kesme alanını ve sözcük parçalarını da yapar. (Örn: Anneye Güve ...)

String.prototype.truc= function (length) {
        return this.length>length ? this.substring(0, length) + '&hellip;' : this;
};

kullanımı:

"this is long length text".trunc(10);
"1234567890".trunc(5);

çıktı:

bu lo ...

12345 ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.