简介
本文介绍了一种自定义 v -ellipsis 指令的计划,当文本超出时显示省略号且鼠标移入时浮层显示残缺文本
效果图
全局注册
vue3 全局注册指令
import {setupEllipsisDirective} from "@/directives/ellipsis";
setupEllipsisDirective(app);
vue2 版本只需引入 ellipsis.js 文件即可
应用示例
<div v-ellipsis style="width: 100px">
文本超出测试文本超出测试文本超出测试文本超出测试文本超出测试文本超出测试
</div>
当传入 false 时指令不失效,用于须要应用变量管制是否超出省略的状况
<div v-ellipsis="false" style="width: 100px">
文本超出测试文本超出测试文本超出测试文本超出测试文本超出测试文本超出测试
</div>
源码(vue3 + ts)
// directives/ellipsis.ts
import type {App, Directive, DirectiveBinding} from "vue";
let tooltipDom: HTMLElement;
const ellipsisDirective: Directive = {mounted(el: HTMLElement, bindings: DirectiveBinding) {bindEvent(el, bindings);
},
updated(el: HTMLElement, bindings: DirectiveBinding) {bindEvent(el, bindings);
},
unmounted() {removeTooltip();
},
};
function bindEvent(el: HTMLElement, bindings: DirectiveBinding) {
// 先移除上一次绑定的事件
el.removeEventListener("mouseenter", handleMouseEnter);
el.removeEventListener("mouseleave", removeTooltip);
if (bindings.value === false) {return;}
// 给以后元素设置超出暗藏
el.style.overflow = "hidden";
el.style.textOverflow = "ellipsis";
el.style.whiteSpace = "nowrap";
// 如果超出,绑定鼠标移入移出事件
if (el.scrollWidth > el.offsetWidth) {el.addEventListener("mouseenter", handleMouseEnter);
// 鼠标移出 将提示信息移除
el.addEventListener("mouseleave", removeTooltip);
}
}
/** 鼠标移入事件 */
function handleMouseEnter(e) {if (!tooltipDom) {
// 创立浮层元素
tooltipDom = document.createElement("div");
// 将浮层插入到 body 中
document.body.appendChild(tooltipDom);
}
const maxWidth = 600;
let cssText = `
max-width: ${maxWidth}px;
overflow: auto;
position: fixed;
background: #262627;
color: #fff;
border-radius: 4px;
line-height: 20px;
padding: 10px;
display: block;
font-size: 12px;
z-index: 99999;
word-break: break-all;
`;
// 依据鼠标移入地位判断浮层位于左侧还是右侧,防止遮挡
if (window.innerWidth - e.clientX < maxWidth) {cssText += `right:${window.innerWidth - e.clientX}px;`;
} else {cssText += `left:${e.clientX + 20}px;`;
}
// 依据鼠标移入地位判断浮层位于上方还是下方,防止遮挡
if (window.innerHeight - e.clientY < 600) {cssText += `bottom:${window.innerHeight - e.clientY}px;`;
} else {cssText += `top:${e.clientY}px;`;
}
tooltipDom.style.cssText = cssText;
// 浮层中的文字
tooltipDom.innerHTML = e.currentTarget.innerText;
}
function removeTooltip() {
// 暗藏浮层
if (tooltipDom) {tooltipDom.style.display = "none";}
}
export function setupEllipsisDirective(app: App) {app.directive("ellipsis", ellipsisDirective);
}
源码(vue2 + js)
import Vue from "vue";
let tooltipDom;
Vue.directive("ellipsis", {inserted(el, bindings) {bindEvent(el, bindings);
},
componentUpdated(el, bindings) {bindEvent(el, bindings);
},
unbind() {removeTooltip();
},
});
function bindEvent(el, bindings) {
// 先移除上一次绑定的事件
el.removeEventListener("mouseenter", handleMouseEnter);
el.removeEventListener("mouseleave", removeTooltip);
if (bindings.value === false) {return;}
// 给以后元素设置超出暗藏
el.style.overflow = "hidden";
el.style.textOverflow = "ellipsis";
el.style.whiteSpace = "nowrap";
// 如果超出,绑定鼠标移入移出事件
if (el.scrollWidth > el.offsetWidth) {el.addEventListener("mouseenter", handleMouseEnter);
// 鼠标移出 将提示信息移除
el.addEventListener("mouseleave", removeTooltip);
}
}
/** 鼠标移入事件 */
function handleMouseEnter(e) {if (!tooltipDom) {
// 创立浮层元素
tooltipDom = document.createElement("div");
// 将浮层插入到 body 中
document.body.appendChild(tooltipDom);
}
const maxWidth = 600;
let cssText = `
max-width: ${maxWidth}px;
overflow: auto;
position: fixed;
background: #262627;
color: #fff;
border-radius: 4px;
line-height: 20px;
padding: 10px;
display: block;
font-size: 12px;
z-index: 99999;
word-break: break-all;
`;
// 依据鼠标移入地位判断浮层位于左侧还是右侧,防止遮挡
if (window.innerWidth - e.clientX < maxWidth) {cssText += `right:${window.innerWidth - e.clientX}px;`;
} else {cssText += `left:${e.clientX + 20}px;`;
}
// 依据鼠标移入地位判断浮层位于上方还是下方,防止遮挡
if (window.innerHeight - e.clientY < 600) {cssText += `bottom:${window.innerHeight - e.clientY}px;`;
} else {cssText += `top:${e.clientY}px;`;
}
tooltipDom.style.cssText = cssText;
// 浮层中的文字
tooltipDom.innerHTML = e.currentTarget.innerText;
}
function removeTooltip() {
// 暗藏浮层
if (tooltipDom) {tooltipDom.style.display = "none";}
}