vue如何判断文字是否溢出ellipsis?

给文字设置了text-overflow:ellipsis

但我想要

  • 在文字显示...的时候,鼠标放上去会有tooltip显示完整字节
  • 完整显示的时候,鼠标放上去不显示tooltip

所以在写tooltip的显示状况必须得提前判断当前文字是否溢出

请问在vue里要如何判断文字是否溢出呢?

我一开始是估计的一个最大字符串长度值,但因为英文标点符合和中文的长度不一样,导致这个长度判断并不准确

所以有什么办法能精准判断文字是否溢出呢?(在文字可能包含标点英文中文的情况下)

阅读 16.6k
4 个回答
computed: {
    lens: function () {
        var lens = 0; // 中文算2个字
        for (i = 0; i < this.message.length; i++) {
           if ((this.message.charCodeAt(i) >= 0) && (this.message.charCodeAt(i) <= 255))
               { lens = lens + 1;}
           else{ lens = lens + 2; } 
        }
        return lens;
    } 
},

给文字容器,比如section设置一个高度,为了不出现显示变化,你可以先将它opacity:0,然后将整行文字放入,判断改容器高度是否大约你给的高度,大于表示文字溢出了。

套一层就可以了

<div>
    <span ref="test">啦啦啦啦啦啦啦啦啦啦啦啦</span>
</div>
div{
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 50px;
    overflow: hidden;
}
mounted() {
    var  width = this.$refs.test.offsetWidth
    console.log(width) // 判断这个宽度是否大于容器
}

2020/7/28。 如题主所述,本人今天也遇到了类似的需求。我的解决方案如下:

// 判断文本是否溢出
export function checkEllipsis(elem) {
  let old, now;
  let newNode = elem.cloneNode(true);
  let result = copyStyle(elem)
  newNode.style.width = "auto";
  newNode.style.visibility = "visible";
  newNode.style.display = "inline-block"
  result.forEach(item => {
    newNode.style[item.name] = item.value
  })
  document.body.appendChild(newNode);
  old = elem.getBoundingClientRect().width
  now = newNode.getBoundingClientRect().width
  
  if (Math.abs(old - now) > 1) {
    // 溢出了
    newNode.remove()
    return true
  }
  newNode.remove();
  return false
}

思路是拷贝一份原来的节点,用新旧节点的长度做比较,如果不相等,则溢出。需要注意的是,拷贝的新节点是没有样式的,我们知道font-size、font-family、padding等也会影响宽度,所以需要将旧节点的样式复制到新节点中,方法如下:

function copyStyle(elem) {
  let computedStyle;
  const needStyle = ['fontSize', 'fontFamily', 'padding', 'border', 'fontWeight', 'color']
  let result = []
  if (typeof elem.currentStyle != 'undefined') {
  // 兼容IE
    computedStyle = elem.currentStyle;
  } else {
    computedStyle = window.getComputedStyle(elem, null);
  }
  needStyle.forEach(style => {
    result.push({
      name: style,
      value: computedStyle[style]
    })
  })
  return result
}

如果有更好的思路,希望大家一起讨论。
newrank.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题