Obetnij ciąg prosto JavaScript

167

Chciałbym obciąć dynamicznie ładowany ciąg przy użyciu prostego JavaScript. To adres URL, więc nie ma spacji i oczywiście nie obchodzą mnie granice słów, tylko znaki.

Oto co mam:

var pathname = document.referrer; //wont work if accessing file:// paths
document.getElementById("foo").innerHTML = "<a href='" + pathname +"'>" + pathname +"</a>"
Pion
źródło
1
Którą część chcesz skrócić? Twój przykład nie oddaje zbyt dobrze intencji.
Larsenal,
1
oh ok - chcę skrócić adres URL do określonej liczby znaków, aby po ustawieniu wewnętrznego HTML dla „foo” nie wypływał z elementu div, jeśli jest za długi.
Bob
1
* ale- tylko wewnętrzny kod HTML, a nie sama nazwa ścieżki var.
Bob
1
Dlaczego po prostu nie użyć css, aby ukryć przepełnienie div? overflow: hidden
Samuel
2
@Samuel Ponieważ byłaby to kiepska praktyka pod względem interfejsu użytkownika - jeśli użytkownik spodziewa się zobaczyć adres URL, z którego właśnie przyszedł (document.referrer), a ja go skracam, chcę im wskazać, że widzi tylko część adresu URL i że nie wystąpił błąd. Poza tym metoda, którą proponujesz, przecięłaby postacie na pół, co wyglądałoby okropnie.
Bob

Odpowiedzi:

334

Użyj metody podciągowej :

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

Więc w twoim przypadku:

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
źródło
1
Jeśli chcesz podciąg zaczynający się od 0, to funkcja substr zrobi dokładnie to samo z 3 mniej
znakami
1
substr zachowuje się dziwnie, jeśli ciąg jest krótszy niż length- zwraca puste
RozzA
Jeśli twój "ciąg" jest liczbą, którą również musisz wstawić, .toString().aby przekonwertować ją na ciąg, który substring()może obsłużyć.
not2qubit
16

tak, podciąg. Nie musisz robić Math.min; podciąg z indeksem dłuższym niż długość łańcucha kończy się na oryginalnej długości.

Ale!

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

Jest to błąd. A co jeśli document.referrer miałby apostrof? Lub różne inne znaki, które mają specjalne znaczenie w HTML. W najgorszym przypadku kod atakującego w witrynie odsyłającej może wstrzyknąć JavaScript do Twojej strony, co jest luką w zabezpieczeniach XSS.

Chociaż można ręcznie uciec przed postaciami w nazwie ścieżki, aby temu zapobiec, jest to trochę uciążliwe. Lepiej jest używać metod DOM niż majstrować przy łańcuchach 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
źródło
jestem zdezorientowany, w jaki sposób twoje rozwiązanie pozwala uniknąć luki w zabezpieczeniach?
Bob
10
Kiedy używasz metod DOM, takich jak „createTextNode” i „.href = ...”, bezpośrednio ustawiasz rzeczywistą podstawową wartość zwykłego tekstu. Kiedy piszesz HTML, czy to w pliku HTML, czy za pomocą innerHTML, musisz przestrzegać reguł ucieczki HTML. Więc chociaż 'createTextNode (' A <B&C ')' jest w porządku, z innerHTML musiałbyś powiedzieć 'innerHTML =' A & lt; B & amp; C ''.
bobince
11

Pomyślałem, że dam Sugar.js o . Ma metodę obcięcia, która jest całkiem sprytna.

Z dokumentacji :

Obcina ciąg. O ile podział nie jest prawdziwy, truncate nie podzieli słów, a zamiast tego odrzuci słowo, w którym nastąpiło obcięcie.

Przykład:

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

Wynik:

just sitting on...
Brian
źródło
9
Sugar is a Javascript library that extends native objects… Rozszerzanie obiektów natywnych w JavaScript jest ogólnie uważane za zły pomysł ™.
Jezen Thomas
@JezenThomas Czasami zły pomysł jest najwłaściwszy.
viditkothari
10

Poniższy kod obcina ciąg i nie dzieli słów, a zamiast tego odrzuca słowo, w którym nastąpiło obcięcie. Całkowicie oparte na źródle 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
źródło
2
Byłoby fajnie dodać „...” jeśli wynik! == str;
Leo Caseiro
9

Oto jedna metoda, której możesz użyć. Oto odpowiedź na jedno z wyzwań FreeCodeCamp:

function truncateString(str, num) {


if (str.length > num) {
return str.slice(0, num) + "...";}
 else {
 return str;}}
mandrei100
źródło
6

Zaktualizowana wersja ES6

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
źródło
to zawsze wywołuje podciąg, nawet jeśli nie jest to konieczne ...
Clint Eastwood
@ClintEastwood dobre opinie, zaktualizowałem odpowiedź. Sprawdzanie długości łańcucha w porównaniu z maksymalną długością oznaczało również, że mogłem usunąć stałą showDots i trójskładnik, dzięki czemu byłby bardziej uporządkowany. Twoje zdrowie.
Sam Logan
3

Tak, substringdziała świetnie:

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
źródło
0

na wypadek, gdybyś chciał skrócić słowo.

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
źródło
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
źródło