Обрізати рядок прямим 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-адресу на певну кількість символів, так що коли я встановлю внутрішній HTMLML "foo", він не витікатиме з діва, якщо він занадто довгий.
Боб

1
* але- лише внутрішнійHTML, а не саме ім'я var path.
Боб

1
Чому б просто не використовувати css, щоб приховати переповнення діва? переповнення: приховано
Самуель

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

Відповіді:


334

Використовуйте метод підрядки :

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.

Хоча можна уникати символів у назви шляху вручну, щоб зупинити це, це болісно. Вам краще використовувати методи DOM, ніж обмінюватись з внутрішніми HTMLML-рядками.

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 ") добре, із внутрішнім HTMLML вам слід сказати" innerHTML = "A & B & C" '.
bobince

11

Думав, я хотів би згадати Sugar.js . Він має метод укорочення, який досить розумний.

З документації :

Обрізає рядок. Якщо розділення не відповідає дійсності, усічення не розділить слова, а замість цього відкине слово, де відбулося усічення.

Приклад:

'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 Колись погана ідея є найбільш підходящою ідеєю.
viditkothari

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 хороший відгук, я оновив відповідь. Перевірка довжини рядка проти максимальної довжини також означала, що я можу видалити const 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.