import Vue from "vue"; let timerId = null; let intervalId = null; let isShowTitle = false; let titleNode = null; function removeTitle() { if (!isShowTitle) { clearTimeout(timerId); } else { isShowTitle = false; document.body.removeChild(titleNode); clearInterval(intervalId); } } Vue.directive("title", { bind: function (el, binding) { if (!binding.value) { return; } el.addEventListener( "mousemove", function (e) { if (!isShowTitle) { clearTimeout(timerId); timerId = setTimeout(() => { isShowTitle = true; titleNode = document.createElement("div"); titleNode.style.position = "fixed"; titleNode.style.zIndex = 2147483647; titleNode.style.backgroundColor = "#ffffff"; titleNode.style.borderRadius = "2px"; titleNode.style.border = "1px solid rgba(151, 151, 151, 0.2)"; titleNode.style.padding = "2px 6px"; titleNode.style.fontSize = "12px"; titleNode.style.color = "#323233"; titleNode.innerText = binding.value; titleNode.style.left = e.clientX + 11 + "px"; titleNode.style.top = e.clientY + 18 + "px"; document.body.appendChild(titleNode); if ( e.clientX + 11 + titleNode.offsetWidth > document.documentElement.clientWidth ) { titleNode.style.left = document.documentElement.clientWidth - titleNode.offsetWidth + "px"; } if ( e.clientY + 18 + titleNode.offsetHeight > document.documentElement.clientHeight ) { titleNode.style.top = document.documentElement.clientHeight - titleNode.offsetHeight + "px"; } intervalId = setInterval(() => { if (!document.contains(el)) { removeTitle(); } }, 300); }, 500); } }, { passive: false, } ); el.addEventListener("mouseleave", removeTitle); el.addEventListener("mousedown", removeTitle); el.addEventListener("keydown", removeTitle); el.addEventListener("scroll", removeTitle); el.addEventListener("dragover", removeTitle); el.addEventListener("dragleave", removeTitle); }, });