简体   繁体   中英

truncate a string in the middle with javascript

anyone have a handy method to truncate a string in the middle? Something like:

truncate ('abcdefghi', 8);

would result in

'abc...hi'

UPDATE:

to be a bit more complete

  • if the string is <= maxLength, return the string
  • otherwise, return a version of the string that is maxLength, with a chunk taken out of the middle, and replaced with "...".
  • count the three characters of "..." in the total, so if maxLength is 8, you'll only see 5 characters from the original string

Here's one way to do it chopping up the string with substr :

var truncate = function (fullStr, strLen, separator) {
    if (fullStr.length <= strLen) return fullStr;

    separator = separator || '...';

    var sepLen = separator.length,
        charsToShow = strLen - sepLen,
        frontChars = Math.ceil(charsToShow/2),
        backChars = Math.floor(charsToShow/2);

    return fullStr.substr(0, frontChars) + 
           separator + 
           fullStr.substr(fullStr.length - backChars);
};

See example →

CoffeeScript version based on mVChr's answer :

truncate = (str, length, separator = '...') ->
  return '' if str is null
  return str if str.length <= length

  pad = Math.round (length - separator.length) / 2
  start = str.substr(0, pad)
  end = str.substr(str.length - pad)

  [start, separator, end].join('')

By relying on the @mvChr solution, I propose to use a @pipe with Typescript.
First, You need to create a @pipe helper where you will described the function of truncate.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'truncateString',
})
export class TreeHelperPipe implements PipeTransform {
  transform(fullStr: string, strLen: number, separator: string): any {
    if (fullStr.length < strLen) {
      return fullStr;
    }

    separator = separator || '...';

    const sepLen = separator.length,
      charsToShow = strLen - sepLen,
      frontChars = Math.ceil(charsToShow / 2),
      backChars = Math.floor(charsToShow / 2);

    return (
      fullStr.substr(0, frontChars) +
      separator +
      fullStr.substr(fullStr.length - backChars)
    );
  }
}

After that, you will be able to use your @pipe helper on your template like that :

<span
  class="item-name"
  [text]="item.name | truncateString: 60"
  [title]="item.name"
></span>

I only apply the @pipe to the text and not the title attribute (which displays the text in a flyover window).

Something like this...

function truncate(text, startChars, endChars, maxLength) {
    if (text.length > maxLength) {
        var start = text.substring(0, startChars);
        var end = text.substring(text.length - endChars, text.length);
        while ((start.length + end.length) < maxLength)
        {
            start = start + '.';
        }
        return start + end;
    }
    return text;
}
alert(truncate('abcdefghi',2,2,8));

Or to limit to true ellipsis:

function truncate(text, startChars, endChars, maxLength) {
    if (text.length > maxLength) {
        var start = text.substring(0, startChars);
        var end = text.substring(text.length - endChars, text.length);
        return start + '...' + end;
    }
    return text;
}
alert(truncate('abcdefghi',2,2,8));

jsFiddle

This may be a bit 'heavy' for what you're looking for but there's a jQuery plugin that does this sort of thing.

The "Three Dots" plugin

If you are playing in PHP you can call this, works fine and could be adjusted to JS well I assume.

function middle_dots($crumb, $max=30){
  if(strlen($crumb) > $max)
  $crumb = substr_replace($crumb, '...', $max/2, round(-$max/2));
  return $crumb;
}

echo middle_dots('Some long text here would if longer than 30 chars get some ...');

Enjoy

Steve

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM