Обрезать строку прямо JavaScript


167

Я хотел бы усечь динамически загруженную строку, используя прямой JavaScript. Это URL, поэтому пробелов нет, и мне явно не нужны границы слов, только символы.

Вот что я получил:

var pathname = document.referrer; //wont work if accessing file:// paths
document.getElementById("foo").innerHTML = "<a href='" + pathname +"'>" + pathname +"</a>"

1
Какую часть вы хотите усечь? Ваш пример не очень хорошо передает цель.
Ларсенал

1
о, хорошо, я хочу обрезать URL до определенного количества символов, чтобы при установке innerHTML в «foo» он не вытек из div, если он слишком длинный.
Боб

1
* но - только innerHTML, а не само имя пути var.
Боб

1
Почему бы просто не использовать css, чтобы скрыть переполнение div? переполнение: скрыто
Самуил,

2
@Samuel Потому что было бы плохо практиковать пользовательский интерфейс - если пользователь ожидает увидеть URL, с которого он только что пришел (document.referrer), и я сокращаю его, я хочу указать им, что он видит только часть URL, и что не было ошибки. Кроме того, метод, который вы предлагаете, будет разрезать символы пополам, что будет выглядеть ужасно.
Боб

Ответы:


335

Используйте метод подстроки :

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

Итак, в вашем случае:

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

1
Если вы хотите, чтобы подстрока начиналась с 0, то функция substr будет делать то же самое с меньшим количеством символов (3);)
jackocnr

1
substr ведет себя странно, если строка короче, чем length- возвращает пустое значение
RozzA

Если ваша «строка» - это число, которое вы также должны вставить, .toString().чтобы преобразовать его в строку, которая substring()может обрабатывать.
not2qubit


16

да, подстрока Вам не нужно делать Math.min; подстрока с более длинным индексом, чем длина строки, заканчивается исходной длиной.

Но!

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

Это ошибка. Что если в document.referrer есть апостроф? Или различные другие символы, которые имеют особое значение в HTML. В худшем случае код злоумышленника в реферере может внедрить JavaScript на вашу страницу, что является дырой в безопасности XSS.

Хотя можно избежать символов в pathname вручную, чтобы остановить это, это немного болезненно. Вам лучше использовать методы DOM, чем возиться со строками 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);
}

я запутался, как ваше решение позволяет избежать дыры в безопасности?
Боб

10
Когда вы используете методы DOM, такие как 'createTextNode' и '.href = ...', вы непосредственно устанавливаете реальное значение открытого текста. Когда вы пишете HTML, либо в HTML-файле, либо с помощью innerHTML, вы должны соблюдать правила экранирования HTML. Поэтому, хотя 'createTextNode (' A <B & C ')' в порядке, с innerHTML вы должны будете сказать 'innerHTML =' A & lt; B & amp; C ''.
Бобинц

11

Думаю, я бы упомянул Sugar.js . У этого есть метод усечения, который является довольно умным.

Из документации :

Обрезает строку. Если параметр split не равен true, усечение не будет разбивать слова на части, а вместо этого отбрасывать слово, в котором произошло усечение.

Пример:

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

Вывод:

just sitting on...

9
Sugar is a Javascript library that extends native objects… Расширение нативных объектов в JavaScript обычно считается плохой идеей ™.
Джезен Томас

@JezenThomas Иногда плохая идея - самая подходящая идея.
Видиткотари

10

Следующий код усекает строку и не разбивает слова на части, а вместо этого отбрасывает слово, где произошло усечение. Полностью основано на источнике 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('');
    }

2
Было бы неплохо добавить "...", если результат! == str;
Лев Казейро,

9

Вот один метод, который вы можете использовать. Это ответ на один из вызовов FreeCodeCamp:

function truncateString(str, num) {


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

6

Обновленная версия 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...'

это всегда вызывает подстроку, даже когда это может не понадобиться ...
Клинт Иствуд

@ClintEastwood хорошая обратная связь, я обновил ответ. Проверка длины строки по отношению к максимальной длине также означала, что я мог бы удалить константу showDots и троичную, чтобы сделать ее более аккуратной. Приветствия.
Сэм Логан

3

Да, substringпрекрасно работает

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

0

в случае, если вы хотите усечь по слову.

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


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>

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.