我才发现,我已经整整一年没有写过博客啦,上篇博客还是一年前的今天~~~
先贴上最后博文讲完后要实现的状态:
我要实现的就是这种很小的功能,第一张图中的数据是循环遍历出来的,且class中设置了超出隐藏的效果(多行)。
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 2; //设置两行
我刚开始做的时候是判断了下字符的长度,然后和自己定的一个数字做比较,但是一个非常明显的问题就是:全部中文、全部英文、大小写英文宽度又有不同的情况就比较难判断了。
const getDescriptionLen = description => {
let len = 0;
for (let i = 0; i < description.length; i++) {
const cur = description.charCodeAt(i);
if (cur > 127 || cur === 94) {
len += 2;
} else {
len ++;
}
}
return len;
};
//render中
{
getDescriptionLen(参数) > 28 ? (<Tooltip title={参数}>{参数}</Tooltip>) : 参数
}
我刚才也列举了这种判断方式的缺点,可谓是非常多啊!!!
选择了一种判断高度的实现方式,在div里面加个span标签,div是受style超出隐藏的限制的,但是span标签是不受限制的,所以就判断span的宽、高是否大于div,如果大于了div的宽高的时候就显示Tooltip的数据,否则正常显示,这样一来就解决了我上面提出的哪些问题。
html结构:
div的实际高度:
span的实际高度:
//html中
<div className={cx('param-meaning')} ref={parentDom}>
{
toolTipIsShow ? (
<Tooltip title={description}>
<span>{description}</span>
</Tooltip>
) : (<span ref={childDom}>{description}</span>)
}
</div>
//js
const [parentSize, setParentSize] = useState({});
const [toolTipIsShow, setToolTipIsShow] = useState(false); //保存一个布尔值作为显示的依赖
//通过ref来获取html中的DOM
// div宽度、高度
const parentDom = useCallback(
node => {
if (node !== null) {
const height = node.getBoundingClientRect().height; //div的真实高度
const width = node.getBoundingClientRect().width;
setParentSize({height, width});
}
},
[],
);
// span宽度、高度
const childDom = useCallback(
node => {
if (node !== null && parentSize.height) {
const height = node.getBoundingClientRect().height; //span的真实高度
const width = node.getBoundingClientRect().width;
//判断一下高度是否大于div的高度
if (height > parentSize.height || width > parentSize.width) {
setToolTipIsShow(true);
} else {
setToolTipIsShow(false);
}
}
},
[parentSize],
);
注意的是,这个要单独写在一个组件中,因为每个循环出来的数据都需要根据当前的状态进行判断,每个循环出来的内容都要维护一个自己的状态,所以要单独写在一个组件中,这样才能每个元素维护一个属于自己的状态。
本文中获取 DOM 节点的位置或是大小的基本方式是使用callback ref。官网的链接为:https://react.docschina.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node