useMouseTooltip.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. let t = null
  2. let r = null
  3. let l = null
  4. export function useMouseTooltip() {
  5. const TOOLTIP_WIDTH = 80
  6. const TOOLTIP_HEIGHT = 40
  7. const PADDING = 16
  8. const updateTooltipPosition = (clientX, clientY) => {
  9. const viewportWidth = window.innerWidth
  10. const viewportHeight = window.innerHeight
  11. let x = clientX
  12. let y = clientY
  13. let flipX = false
  14. let flipY = false
  15. if (clientX + TOOLTIP_WIDTH + PADDING > viewportWidth) {
  16. x = clientX - TOOLTIP_WIDTH - PADDING
  17. flipX = true
  18. }
  19. if (clientY + TOOLTIP_HEIGHT + PADDING > viewportHeight) {
  20. y = clientY - TOOLTIP_HEIGHT - PADDING
  21. flipY = true
  22. }
  23. x = Math.max(PADDING, x)
  24. y = Math.max(PADDING, y)
  25. document.documentElement.style.setProperty('--mouse-x', x + 'px')
  26. document.documentElement.style.setProperty('--mouse-y', y + 'px')
  27. document.documentElement.style.setProperty('--tooltip-flip-x', flipX ? 'true' : 'false')
  28. document.documentElement.style.setProperty('--tooltip-flip-y', flipY ? 'true' : 'false')
  29. }
  30. const u = (e, instant = false) => {
  31. if (instant) {
  32. updateTooltipPosition(e.clientX, e.clientY)
  33. }
  34. clearTimeout(t)
  35. t = setTimeout(() => {
  36. updateTooltipPosition(e.clientX, e.clientY)
  37. }, 200)
  38. }
  39. const c = () => {
  40. clearTimeout(t)
  41. document.documentElement.style.removeProperty('--mouse-x')
  42. document.documentElement.style.removeProperty('--mouse-y')
  43. document.documentElement.style.removeProperty('--tooltip-flip-x')
  44. document.documentElement.style.removeProperty('--tooltip-flip-y')
  45. }
  46. const i = () => {
  47. // 鼠标移动 → 节流更新
  48. r = (e) => {
  49. if (e.target.closest('.cursor-pointer')) {
  50. u(e)
  51. }
  52. }
  53. // 鼠标进入新元素 → 🔥 立刻刷新位置(解决你说的问题)
  54. const enter = (e) => {
  55. if (e.target.closest('.cursor-pointer')) {
  56. u(e, true) // 立刻更新
  57. }
  58. }
  59. // 鼠标离开 → 延迟清除
  60. l = (e) => {
  61. if (e.target.closest('.cursor-pointer')) {
  62. clearTimeout(t)
  63. t = setTimeout(() => {
  64. c()
  65. }, 100)
  66. }
  67. }
  68. document.addEventListener('mousemove', r, true)
  69. document.addEventListener('mouseenter', enter, true) // 新增
  70. document.addEventListener('mouseout', l, true)
  71. }
  72. const d = () => {
  73. clearTimeout(t)
  74. c()
  75. if (r) document.removeEventListener('mousemove', r, true)
  76. if (l) document.removeEventListener('mouseout', l, true)
  77. r = null
  78. l = null
  79. }
  80. i()
  81. return d
  82. }