likes
comments
collection
share

浏览器兼容性强的单行多行文本溢出截断省略方案

作者站长头像
站长
· 阅读数 21

浏览器兼容性强的单行多行文本溢出截断省略方案

一、需求描述

多行文本溢出显示省略号...,并隐藏超出部分内容,内容不溢出时不显示省略号, 要求要求能兼容Chrome、IE、Firefox等, 能处理含html代码的字符串避免html结构被截取中断破坏, 能对中英文符号的处理效果(页面宽度省略号位置效果)较好。

二、常见方案一

使用css的-webkit-box,-webkit-line-clamp的处理方式,在兼容性上并不理想,例如IE浏览器就不支持这种实现方式,而残酷的现实是2022年的今天,某些企业(g企、y企、银行),依然要求兼容IE,甚至工作电脑上就只有IE浏览器。

overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
line-height: 25px;
height: 85px;

三、常见方案二

截取固定字符数的方式,例如截取120字,超出部分使用省略号替代,不超出则不截取。这种方式相比方案一,兼容性更好,也有两个缺点:

一是排版效果不够美观,因为英文和数字的单字符占的实际宽度要比中文小,这会产生省略号可能在行中间甚至行首,而不是统一的在行位。

二是对html字符串不友好,有时接口返回的会是包含html代码的字符串,截取可能会破坏html字符串的代码结构,例如一个标签被截取部分。

四、推荐方案

推荐方案的浏览器兼容性说明:实测Chrome 99,Firefox 95,IE 11,Safari 14,在中英文数字等场景均表现良好。对多行和单行文本溢出显示省略号均有良好的效果。

推荐方案的实践效果图

浏览器兼容性强的单行多行文本溢出截断省略方案

推荐方案一:vue指令版

// 在main.js 引入该js文件即可,无需使用Vue.use,注册为全局指令的方式使用

// 创建注册指令文件 directives.js,将使用全局指令的方式实现单行多行文本溢出显示省略号
import Vue from "vue";

/**
 * 文本多行溢出省略处理函数:
 * 要求能兼容Chrome、IE、Firefox等,
 * 能处理含html代码的字符串避免html结构被截取中断破坏,
 * 能对中英文符号的处理效果(页面宽度省略号位置效果)较好。
 
 相比截取固定个数的字符串,这种方式对适用元素的宽高有更高的要求。但截取固定字数字符串在应对包含html代码的字符串时容易破坏代码结构,且单个中引文数字在页面占的宽度有差异。
 * @param el 需要进行文本溢出省略的元素
 */
function textOverflow(el) {
  Vue.nextTick(() => {
    console.log("指令的方式11111111:" + el.innerHTML);
    let text = el.innerHTML;
    // 遍历元素的innerHTML内容,当元素的offsetHeight小于scrollHeight(超出元素的高度溢出换行)时,
    // 设置溢出隐藏(overflow = "hidden")
    // 将末尾的三个文字用...取代,同时跳出for循环
    if (!text || !text.length) return;
    // console.log("指令的方式22222:" + el.innerHTML);
    for (let i = 0; i <= text.length; i++) {
      el.innerHTML = text.substr(0, i);
      // console.log("指令的方式3333:" + el.offsetHeight, el.scrollHeight);
      if (el.offsetHeight < el.scrollHeight) {
        el.style.overflow = "hidden";
        // 截取当前字符串0-倒数第三的区间位置的字符并加上"...",然后赋值给元素的innerHTML
        el.innerHTML = text.substr(0, i - 3) + "...";
        console.log("指令的方式4444:" + el.innerHTML);
        break;
      }
    }
  });
}

// 注册文本溢出省略指令
Vue.directive("text-overflow", textOverflow);

指令版本使用示例

<template>
  <div>
    <div v-for="(item,i) in list" class="item">
      <div v-text-overflow class="title">{{ item.title }}</div>
      <div v-text-overflow class="summary">{{ item.summary }}</div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'overflow',
  data () {
    return {
      list: [
        {
          title:
              '企业管理 aa aa 企业管理企业管理企业管理企业管理企业管理企业管理 ',
          summary:
              'AAA aaa企业管理是对企业生产经营kkk kkkk kkk WWWW WW2284848244284活动进行计划、组织、指挥、协调和控制等一系列活动的总称,是社会化大生产的客观',
        },
        {
          title:
              '企企业管理企业管理企业管理企业管理企业管理企业管理企业管理企业管理企业管理企业管理企业管理业管理',
          summary:
              '企业管理企业管理是对企业生产经营活动进行计划、组织、指挥、协调和控制等一系列活动的总称,是社会化大生产的客观企业管理是对企业生产经营活动进行计划、组织、指挥、协调和控制等一系列活动的总称,是社会化大生产的客观企业管理是对企业生产经营活动进行计划、组织、指挥、协调和控制等一系列活动的总称,是社会化大生产的客观是对企业生产经营活动进行计划、组织、指挥、协调和控制等一系列活动的总称,是社会化大生产的客观',
        },
        {
          title: '企业管理',
          summary:
              'Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb ',
        },
        {
          title: '企业管理 bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb',
          summary:
              'Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb Atomic bomb ',
        },
        {
          title: '企业管理',
          summary:
              '11111 3333 333 333 33333 11111 3333 33333 11111 3333 333 333 33333 11111 3333 333 333 33333 11111 3333 333 333 33333 11111 3333 333 333 33333 11111 3333 333 333 33333 11111 3333 333 333 33333 11111 3333 333 333 33333',
        },
        {
          title: '企业管理',
          summary:
              '企业管理是对企业生产经营活动进行计划、组织、指挥、协调和控制等一系列活动的总称,是社会化大生产的客观',
        },
      ],
    }
  },
}
</script>

<style scoped>
.item {
  width: 350px;
  padding: 20px;
  overflow: hidden;
  text-align: left;
}

.title {
  height: 25px;
  line-height: 25px;
  overflow: hidden;
}

.summary {
  height: 75px;
  line-height: 25px;
  overflow: hidden;
}
</style>

推荐方案二:原生js通过获取class样式处理版

/**
 * 文本多行溢出省略处理函数:
 * 要求能兼容Chrome、IE、Firefox等,
 * 能处理含html代码的字符串避免html结构被截取中断破坏,
 * 能对中英文符号的处理效果(页面宽度省略号位置效果)较好
 * 注意需要在元素被赋值渲染后使用才有效,所以需要在更新数据后调用该方法
 * 例如,在一个通过接口取值赋值后调用
 * knowledgeApi.searchList(params).then((res) => {
 *    this.list = res.rows || [];
 *    this.total = res.total;
 *    this.$common.textOverflowMore();
 * });
 * @param className 指定需要处理文本多行溢出省略的元素的样式名
 */
export function textOverflowMore(className = "cn-text-overflow") {
  // 获取特定样式的标签
  let elList = document.getElementsByClassName(className);
  // 遍历所有具有特定样式名的元素
  for (let i in elList) {
    let el = elList[i];
    let text = el.innerHTML;
    // 遍历元素的innerHTML内容,当元素的offsetHeight小于scrollHeight(超出元素的高度溢出换行)时,
    // 设置溢出隐藏(overflow = "hidden")
    // 将末尾的三个文字用...取代,同时跳出for循环
    if (!text || !text.length) return;
    for (let i = 0; i <= text.length; i++) {
      el.innerHTML = text.substr(0, i);
      if (el.offsetHeight < el.scrollHeight) {
        el.style.overflow = "hidden";
        // 截取当前字符串0-倒数第三的区间位置的字符并加上"...",然后赋值给元素的innerHTML
        el.innerHTML = text.substr(0, i - 3) + "...";
        break;
      }
    }
  }
}