前端中对于:“文字超出tooltip展示,鼠标滑过气泡展示所有内容”,这样的需求是很常见的,element-ui也有专门的组件el-popover组件支持类似需求的实现
要实现这样的效果,使用el-popover组件即可。
{{row.first}}
{{row.first}}
这样一律不做区分内容长短,全部使用气泡,如果内容没有超出容器,也会有气泡展示,略显粗暴。
这样效果其实并不好,实际需求一般还会有一句:如果不超过容器宽度则不展示气泡。即便产品不指出,前端也应该处理一下。因此再做一点优化,对内容做个判断,字数超出一定值才展示气泡,通过if-else实现
{{row.first}}
{{row.first}}
{{row.first}}
或者通过el-popover的disabled属性设置
{{row.first}}
{{row.first}}
但是这样的实现方式无法精确计算出何时会出发tooltips效果,因为tlltips是css实现的,底层是浏览器去计算内容和容器的相对宽度实现的,但并未通过浏览器api给到前台,所以就无法精确控制气泡的出发时机。如果包含一些特殊符号、英文等字符,简单通过长度判断就更不够精确了,比如:
中文长度超过12,css就计算出超出容器,需要tooltips展示,所以气泡也设置为12
但是如果含有英文字符或数字就无法精确了
能看到,长度依然是12,由于英文字符和数字、特殊字符、中文等的宽度各不相同,导致实际容还没超出容器,tooltips还未展示,但气泡通过字符长度这个单一维度判断出已达设置上限,气泡被触发。一般情况下气泡是用来展示固定宽度容器无发展示的更多内容,本身会遮挡一部分其它内容,影响体验,不是必要的时候最好不展示。如果无法精确控制或者说相对更加精确控制的话,就会造成体验上的不佳。
介于此,经过一番研究,问题的本质是内容宽度超出容器宽度时,然后做一些操作,如何能精确呢?就目前看来,js计算是最精确的,能精确到1px。
思路:
利用el-popover做二次封装,通过js计算内容dom的宽度和容器dom宽度,进行比较,动态修改disabled属性。
默认单行tooltips,计算方程:容器宽度 < 内容宽度 时展示气泡;
多行tooltips同理,支持配置行数即可,计算方程:容器宽度 * 行数 < 内容宽度 时展示气泡
代码:
{{popoverValue}}
{{popoverValue}}
{{popoverValue}}
关键之处在于,块标签div默认长度和容器等同,只要div设置强制不换行,内部内连标签span则会随内容撑开,和内容宽度一致,不受div限制
这样就可以分别在组件内计算容器和内容的宽度了
content内容默认通过popoverValue传递
组件支持插槽分别自定义content内容和bubble内容,如果没有插槽,则默认content和bubble内容一致,均为popoverValue;
如果只有content插槽,默认bubble和content内容一致;
如果content内容和bubble内容不同,则content通过popoverValue传递,bubble通过插槽自定义,并设置forceShowBubble属性为true;
通过rows属性设置多行tooltips和气泡;
使用:
{{row.address}}
这样,效果就出来了,虽然还是会有几px的误差,但已经比用字符长度控制精确了很多,基本上都能满足需求了。