文字溢出的多种方式

2020-10-31 loading

# CSS实现单行溢出

<p class="singleLine"> 
    溢出处理、样式处理;溢出处理、样式处理;溢出处理、样式处理;溢出处理、样式处理;溢出处理、样式处理;溢出处理、样式处理;
</p>
p{
  padding:0;
  margin:0;
  line-height: 30px;
}
.singleLine{
  width: 500px;
  height: 30px;
  overflow: hidden; 
  white-space: nowrap; /* 禁止换行 */
  text-overflow: ellipsis; /* 以...结尾 */
}

# CSS实现多行溢出

<p class="manyLine"> 
    多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;多行溢出处理、多行溢出处理;
</p>

<p class="manyLine"> 
  aaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbb
</p>
p{
  padding:0;
  margin:0;
  line-height: 30px;
}
.manyLine{
  width: 500px;
  overflow: hidden; 
  text-overflow: ellipsis; /* 以...结尾 */
  display:-webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  word-break: break-all; /* 连续的英文字符和数字可以换行 */
}

# 通过js+css实现溢出处理

🌰 文字超过3行时,显示“...查看更多”,覆盖在行尾

思路

  • 创建两个文本dom原始p,第一个p为展示的真实内容,第二个为展示所有文本的隐藏dom
  • secondPHeight(隐藏p元素的高度) > lineHeight * 3,则添加后缀“...查看更多”
  • 为了避免覆盖上后缀后,导致文字被强行遮挡(可能遮挡一半),后缀的北京增加逐渐透明的背景

<p class="text" id="text"> 
  多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;
  多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;
  <span class="more" id="more">...显示更多</span>
</p>
<p class="text hidden" id="hiddenText"> 
  多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;
  多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;
</p>
p{
  padding:0;
  margin:0;
  line-height: 30px;
}
.text{
  width: 500px;
  position: relative;
  max-height: 90px;
  overflow: hidden;
}

.text.hidden{
  opacity: 0;
  height: auto;
  max-height: max-content;
}

.more {
  display: none;
  width: 100px;
  text-align: right;
  line-height: 30px;
  position: absolute;
  bottom: 0;
  right: 0;
  background: linear-gradient(to right, rgba(255,255,255,0.6),white,white,white);
  color:green;
}
const text = document.getElementById('text')
const hiddenText = document.getElementById('hiddenText')
const more = document.getElementById('more')
if(hiddenText.clientHeight > 30 * 3){
  more.style.display = 'inline-block'
}

# 通过js+css实现溢出处理

🌰 文字超过3行时,截取适当的文字,并添加后缀“...查看更多”

在上一个情况的基础之上,如果需要添加后缀“...查看更多”时————

  • domWidth / textSize = lineCount(每行可以显示的元素数目) ;lineCount * 3 = firstEndIndex(初次截取文本的位置)
  • 计算firstEndIndex处的文字距离父元素p的top和right值,判断是否需要继续计算末尾的文本

<p class="text" id="textJs"> 
    多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;
    多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;
</p>
<p class="text hidden" id="hiddenText"> 
  多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;
  多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;多行溢出处理、设置文字浙层;
</p>
.moreEnd{
  color:green;
}
    const textJs = document.getElementById('textJs')
    const hiddenText = document.getElementById('hiddenText')

    const lineCount = 3
    const hiddenDomStyle = window.getComputedStyle(hiddenText)
    
    const baseWidth = hiddenDomStyle.width.slice(0,-2);  // 每行的宽度
    const baseFontSize = hiddenDomStyle.fontSize.slice(0,-2); // 字体大小——一个字节的宽度
    const lineHeight = hiddenDomStyle.lineHeight.slice(0,-2); // 行高
    const pHeight = hiddenDomStyle.height.slice(0,-2); // 正常显示所有文本时,p元素的高度
    console.log(baseWidth,baseFontSize,lineHeight,pHeight)

    const overflowText = '...显示更多';

    const [textNode] = hiddenText.childNodes;
    const hiddenTextValue = hiddenText.innerText;
    const hiddenTextFrames = hiddenText.getBoundingClientRect()
    const rightPadding = hiddenTextFrames.right;
    

    const range = document.createRange()
    // 计算指定index的字符的top/right 值
    const getCharacterFrame = start => {
      range.setStart(textNode, start);
      range.setEnd(textNode, start + 1);
      const characterFrames = range.getClientRects();
      const targetFrame = characterFrames[characterFrames.length - 1];
      if(targetFrame){
        return {
          top: targetFrame.top,
          right: targetFrame.right
        }
      }
    }

    window.onload = function(){

      if(pHeight <= lineHeight * lineCount){
        return false
      }

      const lineTextCount = Math.floor(baseWidth / baseFontSize); // 每行容纳的字符数(由于数字/字母/符号占据的宽度是字体大小的一半,所有这个数据只是估算值)
      let totalLineTextCount = lineTextCount * lineCount - overflowText.length;; // 计算满 3行时的,字符数——初步 定位
      
      for (let i=totalLineTextCount;i<hiddenTextValue.length;i++){
        const r = getCharacterFrame(i).right
        if( r + baseFontSize >= rightPadding){
          totalLineTextCount = i;
          break;
        }
      }
      textJs.innerHTML = hiddenTextValue.slice(0, totalLineTextCount) + `<span class="moreEnd">${overflowText}</span>`
    }

# 学习资料