import { ref } from 'vue';
export const tooltipVisible = ref(false);
export const tooltipContent = ref('');
export const tooltipClass = ref('');
export const tooltipTriggerRef = ref({
getBoundingClientRect() {
return tooltipPosition.value;
}
});
const tooltipPosition = ref({
top: 0,
left: 0,
bottom: 0,
right: 0
});
* 功能:给需要超出显示"..."的标签添加类名让其超出显示"...",并且添加tooltip提示信息
* 注册一个全局自定义指令 `v-addTooltip`
* 注意:
* 1. 添加指令 v-addTooltip
* 2. 添加类型修饰符,比如: v-addTooltip.elButton
* 所有的修饰符:elButton(普通按钮)、elRadioButton(radio按钮)、elTag(tag标签)、perLine(单行文本)、td(el-table的展示元素td)
* 3. perLine单行文本比较特殊,可以是span、div或者其他标签,需要在各自的vue文件中设置好最大宽度,
* 4. 支持传内容,比如:v-addTooltip.elButton="{ tooltipClass: 'left-nav-tooltip' }"
*/
export function mouseEventDirective(app: any) {
app.directive('addTooltip', {
mounted(el: any, binding: any) {
defaultAddTooltip(el, binding);
}
});
}
function defaultAddTooltip(el: any, binding: any) {
Object.keys(binding.modifiers).forEach(key => {
switch (key) {
case 'elButton':
elButtonAction(el, binding);
break;
case 'elRadioButton':
elRadioButtonAction(el, binding);
break;
case 'elTag':
elTagMousemoveAction(el, binding);
break;
case 'perLine':
perLineMousemoveAction(el, binding);
break;
case 'td':
tdAction(el, binding);
break;
default:
tooltipVisible.value = false;
break;
}
el.addEventListener('mouseleave', () => {
tooltipVisible.value = false;
tooltipClass.value = '';
});
});
}
function elButtonAction(el: any, binding: any): any {
const childDom: any = el?.children[0];
childDom.classList.add('overflow-show-point-and-add-tooltip');
el.addEventListener('mouseenter', (event: any) => {
const w1 = el?.offsetWidth;
const w2 = el?.children[0]?.scrollWidth;
const content: string = el?.children[0]?.innerText;
const paddingLeft = getDomAimStyle(el, 'padding-left') || 0;
const paddingRight = getDomAimStyle(el, 'padding-right') || 0;
updateTooltip({ w1, w2, paddingLeft, paddingRight, content, event, binding });
});
}
function elRadioButtonAction(el: any, binding: any): any {
const childDom: any = el?.children[1];
childDom?.classList.add('overflow-show-point-and-add-tooltip');
el.addEventListener('mouseenter', (event: any) => {
const w1 = el?.offsetWidth;
const w2 = el?.children[1]?.scrollWidth;
const content: string = el?.children[1]?.innerText;
const paddingLeft = getDomAimStyle(el, 'padding-left') || 0;
const paddingRight = getDomAimStyle(el, 'padding-right') || 0;
updateTooltip({ w1, w2, paddingLeft, paddingRight, content, event, binding });
});
}
function elTagMousemoveAction(el: any, binding: any): any {
const childDom: any = el?.children[0];
childDom.classList.add('overflow-show-point-and-add-tooltip');
el.addEventListener('mouseenter', (event: any) => {
const w1 = el?.offsetWidth;
const w2 = el?.children[0]?.offsetWidth;
const content: string = el?.children[0]?.innerText;
const paddingLeft = getDomAimStyle(el, 'padding-left') || 0;
const paddingRight = getDomAimStyle(el, 'padding-right') || 0;
updateTooltip({ w1, w2, paddingLeft, paddingRight, content, event, binding });
});
}
function perLineMousemoveAction(el: any, binding: any): any {
el.classList.add('overflow-show-point-and-add-tooltip');
el.addEventListener('mouseenter', (event: any) => {
const w1 = el.offsetWidth;
const w2 = el.scrollWidth;
const content: string = el?.innerText;
if (w1 < w2 && content) {
tooltipAddClass(binding);
const x = event.clientX - event.offsetX + w1 / 2;
const y = event.clientY - event.offsetY;
tooltipContent.value = content;
tooltipVisible.value = true;
tooltipPosition.value = DOMRect.fromRect({
width: 0,
height: 0,
x,
y
});
}
});
}
function tdAction(el: any, binding: any) {
el.classList.add('overflow-show-point-and-add-tooltip');
el.addEventListener('mouseenter', (event: any) => {
const w1 = el.parentNode.offsetWidth;
const w2 = el.offsetWidth;
const content: string = el?.innerText;
const paddingLeft = getDomAimStyle(el.parentNode, 'padding-left') || 0;
const paddingRight = getDomAimStyle(el.parentNode, 'padding-right') || 0;
updateTooltip({ w1, w2, paddingLeft, paddingRight, content, event, binding });
});
el.addEventListener('mouseleave', () => {
tooltipVisible.value = false;
});
}
function getDomAimStyle(dom: any, key: string) {
let style = null;
if (window.getComputedStyle) {
style = window.getComputedStyle(dom, null);
} else {
style = dom.currentStyle;
}
if (style) {
const res = style.getPropertyValue(key);
if (res && res.indexOf('px') > 0) {
return parseFloat(res);
} else {
return res;
}
} else {
return undefined;
}
}
function updateTooltip(config: any) {
const { w1, w2, paddingLeft, paddingRight, content, event, binding } = config;
if (w1 < w2 + paddingLeft + paddingRight && content) {
tooltipAddClass(binding);
const x = event.clientX - event.offsetX + w1 / 2;
const y = event.clientY - event.offsetY;
tooltipContent.value = content;
tooltipVisible.value = true;
tooltipPosition.value = DOMRect.fromRect({
width: 0,
height: 0,
x,
y
});
}
}
function tooltipAddClass(binding: any) {
if (binding.value?.tooltipClass) {
tooltipClass.value = binding.value.tooltipClass;
}
}