magiccube-vue3
Version:
vue3-js版组件库
78 lines (73 loc) • 2.84 kB
JavaScript
import store from '../../utils/store'
const TOOLTIP_CLASS_NAME = 'mc-ellipsis-tooltip'
const state = store.getState()
// 支持自定义插入位置
function getTargetEl(){
let el = null
if(state.teleportName) {
el = document.querySelector(`#${state.teleportName}`) || document.querySelector(`.${state.teleportName}`) || document.body
} else {
el = document.body
}
return el
}
function onMouseIn(el, event, targetEl){
const value = el.textContent
if(!value) return false
event.stopPropagation()
event.preventDefault()
const winWidth = document.body.clientWidth
const winHeight = document.body.clientHeight
const mouseX = Math.max(0, event.clientX - event.offsetX)
const mouseY = event.clientY - event.offsetY
const tipWidth = event.target.scrollWidth < 300? 'auto' : 300
const marginMouseTop = 32
const paddingWidth = 24
const x = mouseX + tipWidth + paddingWidth > winWidth? winWidth - (tipWidth + paddingWidth) : mouseX
const div = document.createElement('div')
div.className = TOOLTIP_CLASS_NAME
div.innerText = value
div.style.left = x + 'px'
div.style.width = tipWidth + 'px'
div.style.paddingLeft = paddingWidth / 2 + 'px'
div.style.paddingRight = paddingWidth / 2 + 'px'
div.style.paddingTop = 4 + 'px'
div.style.paddingBottom = 4 + 'px'
div.style.zIndex = 10000
targetEl?.append(div)
const tipHeight = Math.max(div.offsetHeight, 24)
const y = mouseY + tipHeight + marginMouseTop > winHeight? mouseY - tipHeight - 8 : mouseY + marginMouseTop
div.style.minHeight = tipHeight + 'px'
div.style.top = y + 'px'
}
function onMouseOut(el, event, targetEl){
event && event.stopPropagation()
event && event.preventDefault()
const list = targetEl?.children || []
for(let i=0;i<list.length;i++){
const node = list[i]
if(node.className.toString().indexOf(TOOLTIP_CLASS_NAME) > -1) targetEl?.removeChild(node)
}
}
export default {
mounted(el) {
const targetEl = getTargetEl()
el.addEventListener('mouseenter', (e) => {
if(el.children?.length){
const target = el.getBoundingClientRect? el.getBoundingClientRect() : {}
const child = el.children[0] || {}
const childAttr = child.getBoundingClientRect? child.getBoundingClientRect() : {}
if(target.width < childAttr.width) onMouseIn(el, e, targetEl)
} else {
const wrapWidth = el.offsetWidth
const innerWidth = el.scrollWidth
if(wrapWidth < innerWidth) onMouseIn(el, e, targetEl)
}
})
el.addEventListener('mouseleave', (e) => onMouseOut(el, e, targetEl))
},
updated(el) { },
unmounted(el) {
onMouseOut()
}
}