Tronquer une chaîne directement en JavaScript

167

Je voudrais tronquer une chaîne chargée dynamiquement en utilisant du JavaScript simple. C'est une URL, donc il n'y a pas d'espaces, et je ne me soucie évidemment pas des limites des mots, juste des caractères.

Voici ce que j'ai:

var pathname = document.referrer; //wont work if accessing file:// paths
document.getElementById("foo").innerHTML = "<a href='" + pathname +"'>" + pathname +"</a>"
Bob
la source
1
Quelle partie souhaitez-vous tronquer? Votre exemple ne transmet pas très bien l'intention.
Larsenal
1
oh ok- Je veux tronquer l'URL à un certain nombre de caractères, de sorte que lorsque je règle le innerHTML de "foo", il ne sort pas du div s'il est trop long.
Bob
1
* mais- juste le innerHTML, pas le chemin var lui-même.
Bob
1
Pourquoi ne pas simplement utiliser css pour masquer le débordement du div? débordement: caché
Samuel
2
@Samuel Parce que ce serait une mauvaise pratique en termes d'interface utilisateur - si l'utilisateur s'attend à voir l'URL d'où il vient (document.referrer), et que je la raccourcis, je veux leur indiquer qu'il ne voit qu'une partie de l'url, et qu'il n'y a pas eu d'erreur. En dehors de cela, la méthode que vous proposez couperait les caractères en deux, ce qui aurait l'air horrible.
Bob

Réponses:

335

Utilisez la méthode de sous - chaîne :

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

Donc dans votre cas:

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
la source
1
Si vous voulez une sous-chaîne commençant à 0, alors la fonction substr fera exactement la même chose avec 3 caractères de moins;)
jackocnr
1
substr se comporte bizarrement si la chaîne est plus courte que le length- retourne vide
RozzA
Si votre "chaîne" est un nombre, vous devez également insérer .toString().pour le convertir en une chaîne qui substring()peut gérer.
not2qubit le
16

oui, sous-chaîne. Vous n'avez pas besoin de faire un Math.min; La sous-chaîne avec un index plus long que la longueur de la chaîne se termine à la longueur d'origine.

Mais!

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

C'est une erreur. Et si document.referrer avait une apostrophe dans? Ou divers autres caractères qui ont une signification particulière en HTML. Dans le pire des cas, le code de l'attaquant dans le référent pourrait injecter du JavaScript dans votre page, ce qui est une faille de sécurité XSS.

Bien qu'il soit possible d'échapper manuellement aux personnages du chemin d'accès pour empêcher cela, c'est un peu pénible. Il vaut mieux utiliser les méthodes DOM que jouer avec les chaînes 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
la source
Je suis confus, comment votre solution évite-t-elle le trou de sécurité?
Bob
10
Lorsque vous utilisez des méthodes DOM telles que 'createTextNode' et '.href = ...', vous définissez directement la valeur réelle du texte brut sous-jacent. Lorsque vous écrivez du HTML, que ce soit dans un fichier HTML ou via innerHTML, vous devez respecter les règles d'échappement HTML. Ainsi, alors que 'createTextNode (' A <B&C ')' convient, avec innerHTML vous devrez dire 'innerHTML =' A & lt; B & amp; C ''.
bobince
11

Je pensais que je donnerais à Sugar.js une mention à . Il a une méthode tronquée qui est assez intelligente.

De la documentation :

Tronque une chaîne. À moins que split ne soit vrai, truncate ne divisera pas les mots et rejettera à la place le mot où la troncature s'est produite.

Exemple:

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

Production:

just sitting on...
Brian
la source
9
Sugar is a Javascript library that extends native objects… L'extension d'objets natifs en JavaScript est généralement considérée comme une Bad Idea ™.
Jezen Thomas
@JezenThomas Parfois, une mauvaise idée est l'idée la plus appropriée.
viditkothari
10

Le code suivant tronque une chaîne et ne divisera pas les mots, mais rejettera à la place le mot où la troncature s'est produite. Totalement basé sur la source 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
la source
2
Ce serait bien d'ajouter un "..." si result! == str;
Leo Caseiro
9

Voici une méthode que vous pouvez utiliser. Voici la réponse à l'un des défis de FreeCodeCamp:

function truncateString(str, num) {


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

Version ES6 mise à jour

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
la source
cela invoque toujours la sous-chaîne, même si cela n'est peut-être pas nécessaire ...
Clint Eastwood
@ClintEastwood bonne rétroaction, j'ai mis à jour la réponse. La vérification de la longueur de la chaîne par rapport à la longueur maximale signifiait également que je pouvais supprimer les showDots const et ternaire pour le rendre plus net. À votre santé.
Sam Logan le
3

Oui, substringfonctionne très bien:

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
la source
0

au cas où vous voudriez tronquer par mot.

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
la source
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
la source