截断长字符串的智能方法

发布于 2024-07-30 00:27:17 字数 170 浏览 8 评论 0 原文

有没有人有更复杂的解决方案/库,用于使用 JavaScript 截断字符串并在末尾添加省略号,而不是显而易见的解决方案/库:

if (string.length > 25) {
  string = string.substring(0, 24) + "...";
}

Does anyone have a more sophisticated solution/library for truncating strings with JavaScript and putting an ellipsis on the end, than the obvious one:

if (string.length > 25) {
  string = string.substring(0, 24) + "...";
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(28

凤舞天涯 2024-08-06 00:27:20

(JS) 使用切片和模板文字。

${myString}.slice(0, 20) ...

(JS) Using Slice and Template Literals.

${myString}.slice(0, 20) ...

总以为 2024-08-06 00:27:20

在现代 JS + TypeScript 中重新实现 Lodash 截断:

  • 支持省略/省略(“...”)
  • 可配置的分隔符模式(通常您需要“”)
  • 可配置的最大长度(默认为 30)
// File truncate.ts

type Options = {
  /**
   * The maximum string length.
   *
   * Default: 30
   */
  length?: number;

  /**
   * The string to indicate text is omitted.
   *
   * Also named [ellipsis](https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow)
   *
   * Default: "...", you might want to use "…" (… U+02026) instead
   */
  omission?: string;

  /**
   * The separator pattern to truncate to.
   *
   * Default: none
   */
  separator?: string;
};

/**
 * Truncates a string if it's longer than the given maximum length.
 * The last characters of the truncated string are replaced with the omission
 * string which defaults to "...".
 *
 * @param str The string to truncate
 * @param options The options object
 * @returns The truncated string
 */
export function truncate(str: string, options?: Options) {
  // https://stackoverflow.com/q/1199352
  // https://github.com/Maggi64/moderndash/issues/155
  // https://lodash.com/docs/4.17.15#truncate

  const { length = 30, omission = '...', separator } = options ?? {};

  if (str.length <= length) {
    return str;
  }

  let maxLength = length - omission.length;
  if (maxLength < 0) {
    maxLength = 0;
  }
  const subString = str.slice(
    0,
    // FYI .slice() is OK if maxLength > text.length
    maxLength
  );

  return (separator ? subString.slice(0, subString.lastIndexOf(separator)) : subString) + omission;
}

通过 Lodash 的所有测试:

// File truncate.test.ts

import { truncate } from './truncate';

// Copy-pasted and adapted from https://github.com/lodash/lodash/blob/c7c70a7da5172111b99bb45e45532ed034d7b5b9/test/truncate.spec.js
// See also https://github.com/lodash/lodash/pull/5815

const string = 'hi-diddly-ho there, neighborino';

it('should use a default `length` of `30`', () => {
  expect(truncate(string)).toBe('hi-diddly-ho there, neighbo...');
});

it('should not truncate if `string` is <= `length`', () => {
  expect(truncate(string, { length: string.length })).toBe(string);
  expect(truncate(string, { length: string.length + 2 })).toBe(string);
});

it('should truncate string the given length', () => {
  expect(truncate(string, { length: 24 })).toBe('hi-diddly-ho there, n...');
});

it('should support a `omission` option', () => {
  expect(truncate(string, { omission: ' [...]' })).toBe('hi-diddly-ho there, neig [...]');
});

it('should support empty `omission` option', () => {
  expect(truncate(string, { omission: '' })).toBe('hi-diddly-ho there, neighborin');
});

it('should support a `length` option', () => {
  expect(truncate(string, { length: 4 })).toBe('h...');
});

it('should support a `separator` option', () => {
  expect(truncate(string, { length: 24, separator: ' ' })).toBe('hi-diddly-ho there,...');
});

it('should treat negative `length` as `0`', () => {
  [0, -2].forEach(length => {
    expect(truncate(string, { length })).toBe('...');
  });
});

it('should work as an iteratee for methods like `_.map`', () => {
  const actual = [string, string, string].map(str => truncate(str));
  const truncated = 'hi-diddly-ho there, neighbo...';

  expect(actual).toEqual([truncated, truncated, truncated]);
});

Re-implementation of Lodash truncate in modern JS + TypeScript :

  • Supports omission/ellipsis ("...")
  • Configurable separator pattern (in general you want " ")
  • Configurable max length (default is 30)
// File truncate.ts

type Options = {
  /**
   * The maximum string length.
   *
   * Default: 30
   */
  length?: number;

  /**
   * The string to indicate text is omitted.
   *
   * Also named [ellipsis](https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow)
   *
   * Default: "...", you might want to use "…" (… U+02026) instead
   */
  omission?: string;

  /**
   * The separator pattern to truncate to.
   *
   * Default: none
   */
  separator?: string;
};

/**
 * Truncates a string if it's longer than the given maximum length.
 * The last characters of the truncated string are replaced with the omission
 * string which defaults to "...".
 *
 * @param str The string to truncate
 * @param options The options object
 * @returns The truncated string
 */
export function truncate(str: string, options?: Options) {
  // https://stackoverflow.com/q/1199352
  // https://github.com/Maggi64/moderndash/issues/155
  // https://lodash.com/docs/4.17.15#truncate

  const { length = 30, omission = '...', separator } = options ?? {};

  if (str.length <= length) {
    return str;
  }

  let maxLength = length - omission.length;
  if (maxLength < 0) {
    maxLength = 0;
  }
  const subString = str.slice(
    0,
    // FYI .slice() is OK if maxLength > text.length
    maxLength
  );

  return (separator ? subString.slice(0, subString.lastIndexOf(separator)) : subString) + omission;
}

Passes all tests from Lodash:

// File truncate.test.ts

import { truncate } from './truncate';

// Copy-pasted and adapted from https://github.com/lodash/lodash/blob/c7c70a7da5172111b99bb45e45532ed034d7b5b9/test/truncate.spec.js
// See also https://github.com/lodash/lodash/pull/5815

const string = 'hi-diddly-ho there, neighborino';

it('should use a default `length` of `30`', () => {
  expect(truncate(string)).toBe('hi-diddly-ho there, neighbo...');
});

it('should not truncate if `string` is <= `length`', () => {
  expect(truncate(string, { length: string.length })).toBe(string);
  expect(truncate(string, { length: string.length + 2 })).toBe(string);
});

it('should truncate string the given length', () => {
  expect(truncate(string, { length: 24 })).toBe('hi-diddly-ho there, n...');
});

it('should support a `omission` option', () => {
  expect(truncate(string, { omission: ' [...]' })).toBe('hi-diddly-ho there, neig [...]');
});

it('should support empty `omission` option', () => {
  expect(truncate(string, { omission: '' })).toBe('hi-diddly-ho there, neighborin');
});

it('should support a `length` option', () => {
  expect(truncate(string, { length: 4 })).toBe('h...');
});

it('should support a `separator` option', () => {
  expect(truncate(string, { length: 24, separator: ' ' })).toBe('hi-diddly-ho there,...');
});

it('should treat negative `length` as `0`', () => {
  [0, -2].forEach(length => {
    expect(truncate(string, { length })).toBe('...');
  });
});

it('should work as an iteratee for methods like `_.map`', () => {
  const actual = [string, string, string].map(str => truncate(str));
  const truncated = 'hi-diddly-ho there, neighbo...';

  expect(actual).toEqual([truncated, truncated, truncated]);
});
゛清羽墨安 2024-08-06 00:27:20

此函数还截断空格和单词部分。(例如:Mother into Moth...)

String.prototype.truc= function (length) {
        return this.length>length ? this.substring(0, length) + '…' : this;
};

用法:

"this is long length text".trunc(10);
"1234567890".trunc(5);

输出:

这是...

12345...

This function do the truncate space and words parts also.(ex: Mother into Moth...)

String.prototype.truc= function (length) {
        return this.length>length ? this.substring(0, length) + '…' : this;
};

usage:

"this is long length text".trunc(10);
"1234567890".trunc(5);

output:

this is lo...

12345...

长亭外,古道边 2024-08-06 00:27:19

如果你想用 css 而不是 JavaScript 来实现;

.textShortDesc { /*Here we have determined the max number of lines.*/
    display: block; /* or inline-block */
    -o-text-overflow: ellipsis; /* Opera < 11*/
    text-overflow: ellipsis; /* IE, Safari (WebKit), Opera >= 11, FF > 6 */
    word-wrap: break-word;
    overflow: hidden;
    max-height: 2em; /*max-height/line-height=rowCount */
    line-height: 1em;
}

If you want to do it with css instead of JavaScript;

.textShortDesc { /*Here we have determined the max number of lines.*/
    display: block; /* or inline-block */
    -o-text-overflow: ellipsis; /* Opera < 11*/
    text-overflow: ellipsis; /* IE, Safari (WebKit), Opera >= 11, FF > 6 */
    word-wrap: break-word;
    overflow: hidden;
    max-height: 2em; /*max-height/line-height=rowCount */
    line-height: 1em;
}
五里雾 2024-08-06 00:27:19

使用以下代码

 function trancateTitle (title) {
    var length = 10;
    if (title.length > length) {
       title = title.substring(0, length)+'...';
    }
    return title;
}

Use following code

 function trancateTitle (title) {
    var length = 10;
    if (title.length > length) {
       title = title.substring(0, length)+'...';
    }
    return title;
}
哀由 2024-08-06 00:27:19

我赞成 Kooilnc 的解决方案。 非常好的紧凑型解决方案。 我想解决一个小边缘情况。 如果有人出于某种原因输入了非常长的字符序列,它不会被截断:

function truncate(str, n, useWordBoundary) {
    var singular, tooLong = str.length > n;
    useWordBoundary = useWordBoundary || true;

    // Edge case where someone enters a ridiculously long string.
    str = tooLong ? str.substr(0, n-1) : str;

    singular = (str.search(/\s/) === -1) ? true : false;
    if(!singular) {
      str = useWordBoundary && tooLong ? str.substr(0, str.lastIndexOf(' ')) : str;
    }

    return  tooLong ? str + '…' : str;
}

I upvoted Kooilnc's solution. Really nice compact solution. There's one small edge case that I would like to address. If someone enters a really long character sequence for whatever reason, it won't get truncated:

function truncate(str, n, useWordBoundary) {
    var singular, tooLong = str.length > n;
    useWordBoundary = useWordBoundary || true;

    // Edge case where someone enters a ridiculously long string.
    str = tooLong ? str.substr(0, n-1) : str;

    singular = (str.search(/\s/) === -1) ? true : false;
    if(!singular) {
      str = useWordBoundary && tooLong ? str.substr(0, str.lastIndexOf(' ')) : str;
    }

    return  tooLong ? str + '…' : str;
}
梦里梦着梦中梦 2024-08-06 00:27:19

我不确定这是否算聪明,但它很简洁:

truncateStringToLength (string, length) {
  return (string.length > length)
    ? `${string.substring(0, length)} …`
    : string
}

……然后:

truncateStringToLength('Lorem ipsum dolor sit amet, consetetur sadipscing', 20)

I'm not sure if this qualifies as smart, but it's succinct and simple:

truncateStringToLength (string, length) {
  return (string.length > length)
    ? `${string.substring(0, length)} …`
    : string
}

… then:

truncateStringToLength('Lorem ipsum dolor sit amet, consetetur sadipscing', 20)
囍笑 2024-08-06 00:27:19

这是我的字边界解决方案。

let s = "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
let s_split = s.split(/\s+/);
let word_count = 0;
let result = "";
//1
for(let i = 0; word_count < 100; i++){
  word_count += s_split[i].length+1;
  result += (s_split[i] + " ");
}
console.log(result);
// 2
word_count = 0;
result = s_split.reduce((x,y)=>{
  word_count+=(y.length+1);
  if(word_count>=100) return x;
  else return x+" "+y;}, "").substring(1);
console.log(result);

Here are my solutions with word boundary.

let s = "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
let s_split = s.split(/\s+/);
let word_count = 0;
let result = "";
//1
for(let i = 0; word_count < 100; i++){
  word_count += s_split[i].length+1;
  result += (s_split[i] + " ");
}
console.log(result);
// 2
word_count = 0;
result = s_split.reduce((x,y)=>{
  word_count+=(y.length+1);
  if(word_count>=100) return x;
  else return x+" "+y;}, "").substring(1);
console.log(result);

红墙和绿瓦 2024-08-06 00:27:19

聪明的地方:D

//My Huge Huge String
    let tooHugeToHandle = `It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).`
    
//Trim Max Length
 const maxValue = 50
// The barber.
 const TrimMyString = (string, maxLength, start = 0) => {
//Note - `start` is if I want to start after some point of the string
    	if (string.length > maxLength) {
    	let trimmedString = string.substr(start, maxLength)
    	 return (
    	   trimmedString.substr(
    	   start,
    	   Math.min(trimmedString.length,   trimmedString.lastIndexOf(' '))
           ) + ' ...'
         )
       }
    return string
}

console.log(TrimMyString(tooHugeToHandle, maxValue))

Somewhere Smart :D

//My Huge Huge String
    let tooHugeToHandle = `It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).`
    
//Trim Max Length
 const maxValue = 50
// The barber.
 const TrimMyString = (string, maxLength, start = 0) => {
//Note - `start` is if I want to start after some point of the string
    	if (string.length > maxLength) {
    	let trimmedString = string.substr(start, maxLength)
    	 return (
    	   trimmedString.substr(
    	   start,
    	   Math.min(trimmedString.length,   trimmedString.lastIndexOf(' '))
           ) + ' ...'
         )
       }
    return string
}

console.log(TrimMyString(tooHugeToHandle, maxValue))

眉黛浅 2024-08-06 00:27:19

我最近不得不这样做,结果是:

/**
 * Truncate a string over a given length and add ellipsis if necessary
 * @param {string} str - string to be truncated
 * @param {integer} limit - max length of the string before truncating
 * @return {string} truncated string
 */
function truncate(str, limit) {
    return (str.length < limit) ? str : str.substring(0, limit).replace(/\w{3}$/gi, '...');
}

对我来说感觉很好,很干净:)

I recently had to do this and ended up with:

/**
 * Truncate a string over a given length and add ellipsis if necessary
 * @param {string} str - string to be truncated
 * @param {integer} limit - max length of the string before truncating
 * @return {string} truncated string
 */
function truncate(str, limit) {
    return (str.length < limit) ? str : str.substring(0, limit).replace(/\w{3}$/gi, '...');
}

Feels nice and clean to me :)

但可醉心 2024-08-06 00:27:19

通过快速谷歌搜索,我发现 这个...这对你有用吗?

/**
 * Truncate a string to the given length, breaking at word boundaries and adding an elipsis
 * @param string str String to be truncated
 * @param integer limit Max length of the string
 * @return string
 */
var truncate = function (str, limit) {
    var bits, i;
    if (STR !== typeof str) {
        return '';
    }
    bits = str.split('');
    if (bits.length > limit) {
        for (i = bits.length - 1; i > -1; --i) {
            if (i > limit) {
                bits.length = i;
            }
            else if (' ' === bits[i]) {
                bits.length = i;
                break;
            }
        }
        bits.push('...');
    }
    return bits.join('');
};
// END: truncate

With a quick Googling I found this... Does that work for you?

/**
 * Truncate a string to the given length, breaking at word boundaries and adding an elipsis
 * @param string str String to be truncated
 * @param integer limit Max length of the string
 * @return string
 */
var truncate = function (str, limit) {
    var bits, i;
    if (STR !== typeof str) {
        return '';
    }
    bits = str.split('');
    if (bits.length > limit) {
        for (i = bits.length - 1; i > -1; --i) {
            if (i > limit) {
                bits.length = i;
            }
            else if (' ' === bits[i]) {
                bits.length = i;
                break;
            }
        }
        bits.push('...');
    }
    return bits.join('');
};
// END: truncate
維他命╮ 2024-08-06 00:27:19

我认为 c_harm 的答案是最好的。 请注意,如果您想使用,

"My string".truncate(n)

则必须使用正则表达式对象构造函数而不是文字。 此外,在转换时您必须转义 \S

String.prototype.truncate =
    function(n){
        var p  = new RegExp("^.{0," + n + "}[\\S]*", 'g');
        var re = this.match(p);
        var l  = re[0].length;
        var re = re[0].replace(/\s$/,'');

        if (l < this.length) return re + '…';
    };

c_harm's answer is in my opinion the best. Please note that if you want to use

"My string".truncate(n)

you will have to use a regexp object constructor rather than a literal. Also you'll have to escape the \S when converting it.

String.prototype.truncate =
    function(n){
        var p  = new RegExp("^.{0," + n + "}[\\S]*", 'g');
        var re = this.match(p);
        var l  = re[0].length;
        var re = re[0].replace(/\s$/,'');

        if (l < this.length) return re + '…';
    };
酒与心事 2024-08-06 00:27:19

更正Kooilnc的解决方案:

String.prototype.trunc = String.prototype.trunc ||
  function(n){
      return this.length>n ? this.substr(0,n-1)+'…' : this.toString();
  };

如果不需要截断,则返回字符串值而不是String对象。

Correcting Kooilnc's solution:

String.prototype.trunc = String.prototype.trunc ||
  function(n){
      return this.length>n ? this.substr(0,n-1)+'…' : this.toString();
  };

This returns the string value instead of the String object if it doesn't need to be truncated.

时光病人 2024-08-06 00:27:18

您可以使用 Ext. util.Format.ellipsis 函数(如果您使用的是 Ext.js)。

You can use the Ext.util.Format.ellipsis function if you are using Ext.js.

我的影子我的梦 2024-08-06 00:27:18

文本溢出:省略号是您需要的属性。 有了这个和一个溢出:以特定宽度隐藏,超过这个宽度的所有内容都会在最后得到三个句点效果......不要忘记添加空白:nowrap,否则文本将被放入多行中。

.wrap{
  text-overflow: ellipsis
  white-space: nowrap;
  overflow: hidden;
  width:"your desired width";
}
<p class="wrap">The string to be cut</p>

Text-overflow: ellipsis is the property you need. With this and an overflow:hidden with a specific width, everything surpassing that will get the three period effect at the end ... Don't forget to add whitespace:nowrap or the text will be put in multiple lines.

.wrap{
  text-overflow: ellipsis
  white-space: nowrap;
  overflow: hidden;
  width:"your desired width";
}
<p class="wrap">The string to be cut</p>
贪了杯 2024-08-06 00:27:18

我喜欢使用 .slice() 第一个参数是起始索引,第二个参数是结束索引。 介于两者之间的一切都是你得到的。

var long = "hello there! Good day to ya."
// hello there! Good day to ya.

var short  = long.slice(0, 5)
// hello

I like using .slice() The first argument is the starting index and the second is the ending index. Everything in between is what you get back.

var long = "hello there! Good day to ya."
// hello there! Good day to ya.

var short  = long.slice(0, 5)
// hello
娇柔作态 2024-08-06 00:27:18

大多数现代 Javascript 框架(JQuery原型...)有一个附加到 String 上的实用函数来处理这个问题。

这是原型中的一个示例:

'Some random text'.truncate(10);
// -> 'Some ra...'

这似乎是您希望其他人处理/维护的功能之一。 我会让框架来处理它,而不是编写更多代码。

Most modern Javascript frameworks (JQuery, Prototype, etc...) have a utility function tacked on to String that handles this.

Here's an example in Prototype:

'Some random text'.truncate(10);
// -> 'Some ra...'

This seems like one of those functions you want someone else to deal with/maintain. I'd let the framework handle it, rather than writing more code.

玩物 2024-08-06 00:27:18

这是我的解决方案,它比其他建议有一些改进:

String.prototype.truncate = function(){
    var re = this.match(/^.{0,25}[\S]*/);
    var l = re[0].length;
    var re = re[0].replace(/\s$/,'');
    if(l < this.length)
        re = re + "…";
    return re;
}

// "This is a short string".truncate();
"This is a short string"

// "Thisstringismuchlongerthan25characters".truncate();
"Thisstringismuchlongerthan25characters"

// "This string is much longer than 25 characters and has spaces".truncate();
"This string is much longer…"

它:

  • 截断 25 之后的第一个空格
  • 扩展 JavaScript String 对象
    所以它可以用于(并链接到)
    任何字符串。
  • 如果截断,将修剪字符串
    结果产生尾随空格;
  • 将添加 unicode hellip 实体
    (省略号)如果截断的字符串长度超过 25 个字符

Here's my solution, which has a few improvements over other suggestions:

String.prototype.truncate = function(){
    var re = this.match(/^.{0,25}[\S]*/);
    var l = re[0].length;
    var re = re[0].replace(/\s$/,'');
    if(l < this.length)
        re = re + "…";
    return re;
}

// "This is a short string".truncate();
"This is a short string"

// "Thisstringismuchlongerthan25characters".truncate();
"Thisstringismuchlongerthan25characters"

// "This string is much longer than 25 characters and has spaces".truncate();
"This string is much longer…"

It:

  • Truncates on the first space after 25
    characters
  • Extends the JavaScript String object,
    so it can be used on (and chained to)
    any string.
  • Will trim the string if truncation
    results in a trailing space;
  • Will add the unicode hellip entity
    (ellipsis) if the truncated string is longer than 25 characters
似梦非梦 2024-08-06 00:27:18

我总是使用 cuttr.js 库来截断字符串并添加自定义省略号:

new Cuttr('.container', {
  //options here
  truncate: 'words',
  length: 8,
  ending: '... ►'
});
<script src="https://unpkg.com/[email protected]/dist/cuttr.min.js"></script>
<p class="container">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. </p>

这是我所知道的用 JS 剪切字符串最简单的方法(并且没有任何依赖项),它也可以作为 jQuery 插件使用。

I always use the cuttr.js library to truncate strings and add custom ellipsis:

new Cuttr('.container', {
  //options here
  truncate: 'words',
  length: 8,
  ending: '... ►'
});
<script src="https://unpkg.com/[email protected]/dist/cuttr.min.js"></script>
<p class="container">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. </p>

This is bar far the easiest method (and doesn't have any dependencies) I know to cut strings with JS and its also available as jQuery plugin.

暖阳 2024-08-06 00:27:18

人们希望使用 JavaScript 而不是 CSS 来完成此操作是有充分理由的。

在 JavaScript 中截断为 8 个字符(包括省略号):

short = long.replace(/(.{7})..+/, "$1…");

short = long.replace(/(.{7})..+/, "$1…");

There are valid reasons people may wish to do this in JavaScript instead of CSS.

To truncate to 8 characters (including ellipsis) in JavaScript:

short = long.replace(/(.{7})..+/, "$1…");

or

short = long.replace(/(.{7})..+/, "$1…");
铜锣湾横着走 2024-08-06 00:27:18
('long text to be truncated').replace(/(.{250})..+/, "$1…");

不知何故,上面的代码不适用于 vuejs 应用程序中的某种复制粘贴或书面文本。 所以我使用了 lodash truncate 现在工作正常。

_.truncate('long text to be truncated', { 'length': 250, 'separator': ' '});
('long text to be truncated').replace(/(.{250})..+/, "$1…");

Somehow above code was not working for some kind of copy pasted or written text in vuejs app. So I used lodash truncate and its now working fine.

_.truncate('long text to be truncated', { 'length': 250, 'separator': ' '});
白日梦 2024-08-06 00:27:18

使用 lodash 的截断

_.truncate('hi-diddly-ho there, neighborino');
// → 'hi-diddly-ho there, neighbo…'

下划线.string 的截断

_('Hello world').truncate(5); => 'Hello...'

Use either lodash's truncate

_.truncate('hi-diddly-ho there, neighborino');
// → 'hi-diddly-ho there, neighbo…'

or underscore.string's truncate.

_('Hello world').truncate(5); => 'Hello...'
雪化雨蝶 2024-08-06 00:27:18

我发现的最好的功能。 归功于 text-ellipsis

function textEllipsis(str, maxLength, { side = "end", ellipsis = "..." } = {}) {
  if (str.length > maxLength) {
    switch (side) {
      case "start":
        return ellipsis + str.slice(-(maxLength - ellipsis.length));
      case "end":
      default:
        return str.slice(0, maxLength - ellipsis.length) + ellipsis;
    }
  }
  return str;
}

示例

var short = textEllipsis('a very long text', 10);
console.log(short);
// "a very ..."

var short = textEllipsis('a very long text', 10, { side: 'start' });
console.log(short);
// "...ng text"

var short = textEllipsis('a very long text', 10, { textEllipsis: ' END' });
console.log(short);
// "a very END"

Best function I have found. Credit to text-ellipsis.

function textEllipsis(str, maxLength, { side = "end", ellipsis = "..." } = {}) {
  if (str.length > maxLength) {
    switch (side) {
      case "start":
        return ellipsis + str.slice(-(maxLength - ellipsis.length));
      case "end":
      default:
        return str.slice(0, maxLength - ellipsis.length) + ellipsis;
    }
  }
  return str;
}

Examples:

var short = textEllipsis('a very long text', 10);
console.log(short);
// "a very ..."

var short = textEllipsis('a very long text', 10, { side: 'start' });
console.log(short);
// "...ng text"

var short = textEllipsis('a very long text', 10, { textEllipsis: ' END' });
console.log(short);
// "a very END"
宫墨修音 2024-08-06 00:27:18

所有现代浏览器现在都支持简单的 CSS 解决方案,用于在文本行超过时自动添加省略号可用宽度:(

p {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

请注意,这需要以某种方式限制元素的宽度才能产生任何效果。)

基于 https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/

应该注意的是,这种方法基于字符数进行限制。 如果您需要允许多行文本,它也不起作用

All modern browsers now support a simple CSS solution for automatically adding an ellipsis if a line of text exceeds the available width:

p {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

(Note that this requires the width of the element to be limited in some way in order to have any effect.)

Based on https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/.

It should be noted that this approach does not limit based on the number of characters. It also does not work if you need to allow multiple lines of text.

所谓喜欢 2024-08-06 00:27:18

有时文件名是编号的,索引可能位于开头或结尾。 所以我想从字符串的中心开始缩短:

function stringTruncateFromCenter(str, maxLength) {
    const midChar = "…";      // character to insert into the center of the result
    var left, right;

    if (str.length <= maxLength) return str;

    // length of beginning part      
    left = Math.ceil(maxLength / 2);

    // start index of ending part   
    right = str.length - Math.floor(maxLength / 2) + 1;   

    return str.substr(0, left) + midChar + str.substring(right);
}

请注意,我在这里使用了 UTF-8 中超过 1 个字节的填充字符。

Sometimes file names are numbered, where the index may be at the beginning or the end. So I wanted to shorten from the center of the string:

function stringTruncateFromCenter(str, maxLength) {
    const midChar = "…";      // character to insert into the center of the result
    var left, right;

    if (str.length <= maxLength) return str;

    // length of beginning part      
    left = Math.ceil(maxLength / 2);

    // start index of ending part   
    right = str.length - Math.floor(maxLength / 2) + 1;   

    return str.substr(0, left) + midChar + str.substring(right);
}

Be aware that I used a fill character here with more than 1 byte in UTF-8.

司马昭之心 2024-08-06 00:27:18

也许我错过了一个有人处理空值的例子,但是当我有空值时,3个最佳答案对我不起作用(当然我意识到错误处理和其他数百万件事不是回答问题的人的责任,但因为我使用了一个现有的函数以及一个优秀的截断省略号答案,我想我会为其他人提供它,

例如

javascript:

news.comments

using truncation function

news.comments.trunc(20, true);

但是,在 news.comments 为 null 时,这会“中断”。

Final

checkNull(news.comments).trunc(20, true) 

trunc 函数由 KooiInc 提供

String.prototype.trunc =
 function (n, useWordBoundary) {
     console.log(this);
     var isTooLong = this.length > n,
         s_ = isTooLong ? this.substr(0, n - 1) : this;
     s_ = (useWordBoundary && isTooLong) ? s_.substr(0, s_.lastIndexOf(' ')) : s_;
     return isTooLong ? s_ + '…' : s_;
 };

我的简单 null 检查器(也检查文字“null”)
(这捕获未定义、“”、null、“null”等..)

  function checkNull(val) {
      if (val) {
          if (val === "null") {
              return "";
          } else {
              return val;
          }
      } else {
          return "";
      }
  }

Perhaps I missed an example of where someone is handling nulls, but 3 TOP answers did not work for me when I had nulls ( Sure I realize that error handling is and million other things is NOT the responsibility of the person answering the question, but since I had used an existing function along with one of the excellent truncation ellipsis answers I thought I would provide it for others.

e.g.

javascript:

news.comments

using truncation function

news.comments.trunc(20, true);

However, on news.comments being null this would "break"

Final

checkNull(news.comments).trunc(20, true) 

trunc function courtesy of KooiInc

String.prototype.trunc =
 function (n, useWordBoundary) {
     console.log(this);
     var isTooLong = this.length > n,
         s_ = isTooLong ? this.substr(0, n - 1) : this;
     s_ = (useWordBoundary && isTooLong) ? s_.substr(0, s_.lastIndexOf(' ')) : s_;
     return isTooLong ? s_ + '…' : s_;
 };

My simple null checker (checks for literal "null" thing too
(this catches undefined, "", null, "null", etc..)

  function checkNull(val) {
      if (val) {
          if (val === "null") {
              return "";
          } else {
              return val;
          }
      } else {
          return "";
      }
  }
小嗲 2024-08-06 00:27:17

本质上,您检查给定字符串的长度。 如果它比给定长度 n 长,则将其剪辑为长度 nsubstrslice)并添加 html实体 (...) 到剪切的字符串。

这样的方法看起来像

function truncate(str, n){
  return (str.length > n) ? str.slice(0, n-1) + '…' : str;
};

如果“更复杂”是指在字符串的最后一个单词边界处截断,那么您需要进行额外的检查。
首先,将字符串剪辑到所需的长度,然后将结果剪辑到最后一个单词边界。

function truncate( str, n, useWordBoundary ){
  if (str.length <= n) { return str; }
  const subString = str.slice(0, n-1); // the original check
  return (useWordBoundary 
    ? subString.slice(0, subString.lastIndexOf(" ")) 
    : subString) + "…";
};

您可以使用您的函数扩展本机 String 原型。 在这种情况下,应删除 str 参数,并将函数内的 str 替换为 this

String.prototype.truncate = String.prototype.truncate || 
function ( n, useWordBoundary ){
  if (this.length <= n) { return this; }
  const subString = this.slice(0, n-1); // the original check
  return (useWordBoundary 
    ? subString.slice(0, subString.lastIndexOf(" ")) 
    : subString) + "…";
};

更教条的开发人员可能会因此强烈谴责您(“不要修改不属于您的对象”。不过我不介意)。 [编辑 2023] 扩展字符串而不篡改其原型的方法可能是使用代理。 请参阅此 stackblitz 代码段

一种不扩展 String 原型的方法是创建
您自己的辅助对象,包含您提供的(长)字符串
以及前面提到的截断方法。 这就是片段的内容
下面确实如此。

const LongstringHelper = str => {
  const sliceBoundary = str => str.substr(0, str.lastIndexOf(" "));
  const truncate = (n, useWordBoundary) => 
        str.length <= n ? str : `${ useWordBoundary 
          ? sliceBoundary(str.slice(0, n - 1))
          : str.slice(0, n - 1)}…`;
  return { full: str,  truncate };
}; 
const longStr = LongstringHelper(`Lorem ipsum dolor sit amet, consectetur 
adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore 
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation 
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute 
irure dolor in reprehenderit in voluptate velit esse cillum dolore 
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 
proident, sunt in culpa qui officia deserunt mollit anim id est laborum`);

const plain = document.querySelector("#resultTruncatedPlain");
const lastWord = document.querySelector("#resultTruncatedBoundary");
plain.innerHTML = 
  longStr.truncate(+plain.dataset.truncateat, !!+plain.dataset.onword);
lastWord.innerHTML = 
  longStr.truncate(+lastWord.dataset.truncateat, !!+lastWord.dataset.onword);
document.querySelector("#resultFull").innerHTML = longStr.full;
body {
  font: normal 12px/15px verdana, arial;
}

p {
  width: 450px;
}

#resultTruncatedPlain:before {
  content: 'Truncated (plain) n='attr(data-truncateat)': ';
  color: green;
}

#resultTruncatedBoundary:before {
  content: 'Truncated (last whole word) n='attr(data-truncateat)': ';
  color: green;
}

#resultFull:before {
  content: 'Full: ';
  color: green;
}
<p id="resultTruncatedPlain" data-truncateat="120" data-onword="0"></p>
<p id="resultTruncatedBoundary" data-truncateat="120" data-onword="1"></p>
<p id="resultFull"></p>

最后,您只能使用 css 来截断 HTML 节点中的长字符串。 它给你的控制权较少,但很可能是可行的解决方案。

body {
  font: normal 12px/15px verdana, arial;
  margin: 2rem;
}

.truncate {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 30vw;
}

.truncate:before{
  content: attr(data-longstring);
}

.truncate:hover::before {
  content: attr(data-longstring);
  width: auto;
  height: auto;
  overflow: initial;
  text-overflow: initial;
  white-space: initial;
  background-color: white;
  display: inline-block;
}
<div class="truncate" data-longstring="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."></div>

Essentially, you check the length of the given string. If it's longer than a given length n, clip it to length n (substr or slice) and add html entity (…) to the clipped string.

Such a method looks like

function truncate(str, n){
  return (str.length > n) ? str.slice(0, n-1) + '…' : str;
};

If by 'more sophisticated' you mean truncating at the last word boundary of a string then you need an extra check.
First you clip the string to the desired length, next you clip the result of that to its last word boundary

function truncate( str, n, useWordBoundary ){
  if (str.length <= n) { return str; }
  const subString = str.slice(0, n-1); // the original check
  return (useWordBoundary 
    ? subString.slice(0, subString.lastIndexOf(" ")) 
    : subString) + "…";
};

You can extend the native String prototype with your function. In that case the str parameter should be removed and str within the function should be replaced with this:

String.prototype.truncate = String.prototype.truncate || 
function ( n, useWordBoundary ){
  if (this.length <= n) { return this; }
  const subString = this.slice(0, n-1); // the original check
  return (useWordBoundary 
    ? subString.slice(0, subString.lastIndexOf(" ")) 
    : subString) + "…";
};

More dogmatic developers may chide you strongly for that ("Don't modify objects you don't own". I wouldn't mind though). [edit 2023] A method to extend the String without tampering with its prototype may be to use a Proxy. See this stackblitz snippet.

An approach without extending the String prototype is to create
your own helper object, containing the (long) string you provide
and the beforementioned method to truncate it. That's what the snippet
below does.

const LongstringHelper = str => {
  const sliceBoundary = str => str.substr(0, str.lastIndexOf(" "));
  const truncate = (n, useWordBoundary) => 
        str.length <= n ? str : `${ useWordBoundary 
          ? sliceBoundary(str.slice(0, n - 1))
          : str.slice(0, n - 1)}…`;
  return { full: str,  truncate };
}; 
const longStr = LongstringHelper(`Lorem ipsum dolor sit amet, consectetur 
adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore 
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation 
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute 
irure dolor in reprehenderit in voluptate velit esse cillum dolore 
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 
proident, sunt in culpa qui officia deserunt mollit anim id est laborum`);

const plain = document.querySelector("#resultTruncatedPlain");
const lastWord = document.querySelector("#resultTruncatedBoundary");
plain.innerHTML = 
  longStr.truncate(+plain.dataset.truncateat, !!+plain.dataset.onword);
lastWord.innerHTML = 
  longStr.truncate(+lastWord.dataset.truncateat, !!+lastWord.dataset.onword);
document.querySelector("#resultFull").innerHTML = longStr.full;
body {
  font: normal 12px/15px verdana, arial;
}

p {
  width: 450px;
}

#resultTruncatedPlain:before {
  content: 'Truncated (plain) n='attr(data-truncateat)': ';
  color: green;
}

#resultTruncatedBoundary:before {
  content: 'Truncated (last whole word) n='attr(data-truncateat)': ';
  color: green;
}

#resultFull:before {
  content: 'Full: ';
  color: green;
}
<p id="resultTruncatedPlain" data-truncateat="120" data-onword="0"></p>
<p id="resultTruncatedBoundary" data-truncateat="120" data-onword="1"></p>
<p id="resultFull"></p>

Finally, you can use css only to truncate long strings in HTML nodes. It gives you less control, but may well be viable solution.

body {
  font: normal 12px/15px verdana, arial;
  margin: 2rem;
}

.truncate {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 30vw;
}

.truncate:before{
  content: attr(data-longstring);
}

.truncate:hover::before {
  content: attr(data-longstring);
  width: auto;
  height: auto;
  overflow: initial;
  text-overflow: initial;
  white-space: initial;
  background-color: white;
  display: inline-block;
}
<div class="truncate" data-longstring="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."></div>

舂唻埖巳落 2024-08-06 00:27:17

请注意,这只需要对 Firefox 执行此操作。

所有其他浏览器都支持 CSS 解决方案(请参阅支持表):

p {
    white-space: nowrap;
    width: 100%;                   /* IE6 needs any width */
    overflow: hidden;              /* "overflow" value must be different from  visible"*/ 
    -o-text-overflow: ellipsis;    /* Opera < 11*/
    text-overflow:    ellipsis;    /* IE, Safari (WebKit), Opera >= 11, FF > 6 */
}

讽刺的是我从 Mozilla MDC 获得了该代码片段。

Note that this only needs to be done for Firefox.

All other browsers support a CSS solution (see support table):

p {
    white-space: nowrap;
    width: 100%;                   /* IE6 needs any width */
    overflow: hidden;              /* "overflow" value must be different from  visible"*/ 
    -o-text-overflow: ellipsis;    /* Opera < 11*/
    text-overflow:    ellipsis;    /* IE, Safari (WebKit), Opera >= 11, FF > 6 */
}

The irony is I got that code snippet from Mozilla MDC.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文