Truncar uma cadeia de caracteres JavaScript direto

167

Gostaria de truncar uma string carregada dinamicamente usando JavaScript direto. É um URL, portanto não há espaços e, obviamente, não me importo com limites de palavras, apenas caracteres.

Aqui está o que eu tenho:

var pathname = document.referrer; //wont work if accessing file:// paths
document.getElementById("foo").innerHTML = "<a href='" + pathname +"'>" + pathname +"</a>"
Prumo
fonte
1
Que parte você deseja truncar? Seu exemplo não transmite a intenção muito bem.
Larsenal 19/08/09
1
oh ok- Eu quero truncar o URL em uma certa quantidade de caracteres, para que quando eu defino o HTML interno de "foo" ele não flua para fora da div se for muito longo.
Bob
1
* mas- apenas o innerHTML, não o nome do caminho var.
Bob
1
Por que não usar apenas css para ocultar o estouro da div? overflow: hidden
Samuel
2
@ Samuel Porque seria uma prática inadequada em relação à interface do usuário - se o usuário espera ver o URL de onde veio (document.referrer) e estou diminuindo, quero indicar a eles que eles estão vendo apenas uma parte do URL e que não houve erro. Além disso, o método que você propõe cortaria caracteres ao meio, o que pareceria horrível.
Bob

Respostas:

334

Use o método de substring :

var length = 3;
var myString = "ABCDEFG";
var myTruncatedString = myString.substring(0,length);
// The value of myTruncatedString is "ABC"

Então, no seu caso:

var length = 3;  // set to the number of characters you want to keep
var pathname = document.referrer;
var trimmedPathname = pathname.substring(0, Math.min(length,pathname.length));

document.getElementById("foo").innerHTML =
     "<a href='" + pathname +"'>" + trimmedPathname + "</a>"
Larsenal
fonte
1
Se você quer uma substring a partir de 0, então a função substr vai fazer exatamente a mesma coisa com menos de 3 caracteres;)
jackocnr
1
substr se comportar estranho se a string é menor do que os length- retorna esvaziar
ROZZA
Se a sua "string" for um número, você também precisará inserir .toString().para convertê-la em uma string que substring()possa manipular.
Not2qubit
16

sim, substring. Você não precisa fazer um Math.min; substring com um índice maior que o comprimento da string termina no comprimento original.

Mas!

document.getElementById("foo").innerHTML = "<a href='" + pathname +"'>" + pathname +"</a>"

Isto é um erro. E se document.referrer tivesse um apóstrofo? Ou vários outros caracteres que têm um significado especial em HTML. Na pior das hipóteses, o código do invasor no referenciador pode injetar JavaScript na sua página, que é uma falha de segurança XSS.

Embora seja possível escapar manualmente dos personagens no nome do caminho para impedir que isso aconteça, é um pouco trabalhoso. É melhor usar métodos DOM do que mexer com strings innerHTML.

if (document.referrer) {
    var trimmed= document.referrer.substring(0, 64);
    var link= document.createElement('a');
    link.href= document.referrer;
    link.appendChild(document.createTextNode(trimmed));
    document.getElementById('foo').appendChild(link);
}
bobince
fonte
Estou confuso, como sua solução evita a falha de segurança?
Bob
10
Ao usar métodos DOM como 'createTextNode' e '.href = ...', você está configurando diretamente o valor real do texto sem formatação subjacente. Ao escrever HTML, em um arquivo HTML ou através do innerHTML, você deve obedecer às regras de escape do HTML. Portanto, enquanto 'createTextNode (' A <B&C ')' é bom, com innerHTML você teria que dizer 'innerHTML =' A & lt; B & C; ''.
21909 bobince
11

Pensei em dar Sugar.js mencionar o . Ele tem um método truncado que é bastante inteligente.

A partir da documentação :

Trunca uma string. A menos que a divisão seja verdadeira, truncar não dividirá as palavras e, em vez disso, descartará a palavra onde ocorreu o truncamento.

Exemplo:

'just sittin on the dock of the bay'.truncate(20)

Resultado:

just sitting on...
Brian
fonte
9
Sugar is a Javascript library that extends native objects… A extensão de objetos nativos em JavaScript é geralmente considerada uma Bad Idea ™.
Jezen Thomas
@JezenThomas Às vezes, a má idéia é a mais apropriada.
viditkothari 02/03
10

O código a seguir trunca uma seqüência de caracteres e não dividirá as palavras; em vez disso, descarte a palavra onde ocorreu o truncamento. Totalmente baseado na fonte Sugar.js.

function truncateOnWord(str, limit) {
        var trimmable = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u2028\u2029\u3000\uFEFF';
        var reg = new RegExp('(?=[' + trimmable + '])');
        var words = str.split(reg);
        var count = 0;
        return words.filter(function(word) {
            count += word.length;
            return count <= limit;
        }).join('');
    }
Beto Frega
fonte
2
Seria bom adicionar um "..." se result! == str;
Leo Caseiro
9

Aqui está um método que você pode usar. Esta é a resposta para um dos desafios do FreeCodeCamp:

function truncateString(str, num) {


if (str.length > num) {
return str.slice(0, num) + "...";}
 else {
 return str;}}
mandrei100
fonte
6

Versão ES6 atualizada

const truncateString = (string, maxLength = 50) => {
  if (!string) return null;
  if (string.length <= maxLength) return string;
  return `${string.substring(0, maxLength)}...`;
};

truncateString('what up', 4); // returns 'what...'
Sam Logan
fonte
isso sempre invoca substring, mesmo quando pode não ser necessário ...
Clint Eastwood
@ClintEastwood bom feedback, eu atualizei a resposta. Verificar o comprimento da string versus o comprimento máximo também significava que eu poderia remover a const showDots e o ternário, tornando-a mais organizada. Felicidades.
Sam Logan
3

Sim, substringfunciona muito bem:

stringTruncate('Hello world', 5); //output "Hello..."
stringTruncate('Hello world', 20);//output "Hello world"

var stringTruncate = function(str, length){
  var dots = str.length > length ? '...' : '';
  return str.substring(0, length)+dots;
};
Arnaud Anato
fonte
0

caso você queira truncar por palavra.

function limit(str, limit, end) {

      limit = (limit)? limit : 100;
      end = (end)? end : '...';
      str = str.split(' ');
      
      if (str.length > limit) {
        var cutTolimit = str.slice(0, limit);
        return cutTolimit.join(' ') + ' ' + end;
      }

      return str.join(' ');
    }

    var limit = limit('ILorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus metus magna, maximus a dictum et, hendrerit ac ligula. Vestibulum massa sapien, venenatis et massa vel, commodo elementum turpis. Nullam cursus, enim in semper luctus, odio turpis dictum lectus', 20);

    console.log(limit);

Fhulufhelo Mokhomi
fonte
0

var pa = document.getElementsByTagName('p')[0].innerHTML;
var rpa = document.getElementsByTagName('p')[0];
// console.log(pa.slice(0, 30));
var newPa = pa.slice(0, 29).concat('...');
rpa.textContent = newPa;
console.log(newPa)
<p>
some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here
</p>

sadeq alshaar
fonte