tdesign-mobile-vue
Version:
tdesign-mobile-vue
1 lines • 10.8 kB
Source Map (JSON)
{"version":3,"file":"hover.mjs","sources":["../../src/shared/hover.ts"],"sourcesContent":["import type { Directive, DirectiveBinding } from 'vue';\n\n/*\n * v-hover 指令:在触摸/指针按下短暂延迟后添加 class,结束后保持一段时间再移除。\n * 支持:\n * 1. 绑定值可以是字符串 (作为 className) 或对象 { className, disabledHover, startTime, stayTime }\n * 2. 响应式更新(className / disabledHover 改变)\n * 3. 自动清理(unmounted)\n * 4. 使用 pointer 事件回退到 touch 事件,避免重复触发\n */\n\nexport interface HoverBindingObject {\n className: string; // 必填:需要添加/移除的类名\n disabledHover?: boolean; // 是否禁用\n startTime?: number; // 按下到添加类的延迟(ms)\n stayTime?: number; // 松开到移除类的延迟(ms)\n}\n\ntype HoverBinding = string | HoverBindingObject | undefined;\n\ninterface HoverContext {\n add: () => void;\n remove: () => void;\n downHandler: (e: Event) => void;\n upHandler: (e: Event) => void;\n cancelHandler: (e: Event) => void;\n timers: number[];\n current: Required<Pick<HoverBindingObject, 'className' | 'disabledHover' | 'startTime' | 'stayTime'>>;\n}\n\nconst DEFAULT_DELAY = { startTime: 50, stayTime: 70 };\nconst CTX_KEY: unique symbol = Symbol('v-hover');\n\nfunction resolveBinding(binding: DirectiveBinding<HoverBinding>): HoverContext['current'] {\n if (!binding.value) {\n return { className: '', disabledHover: true, startTime: DEFAULT_DELAY.startTime, stayTime: DEFAULT_DELAY.stayTime };\n }\n if (typeof binding.value === 'string') {\n return {\n className: binding.value,\n disabledHover: false,\n startTime: DEFAULT_DELAY.startTime,\n stayTime: DEFAULT_DELAY.stayTime,\n };\n }\n const {\n className,\n disabledHover = false,\n startTime = DEFAULT_DELAY.startTime,\n stayTime = DEFAULT_DELAY.stayTime,\n } = binding.value;\n return { className, disabledHover, startTime, stayTime };\n}\n\nconst Hover: Directive<HTMLElement, HoverBinding> = {\n created(el, binding) {\n const state = resolveBinding(binding);\n const ctx: HoverContext = {\n current: state,\n timers: [],\n add() {\n if (ctx.current.disabledHover || !ctx.current.className) return;\n // 避免重复添加\n if (!el.classList.contains(ctx.current.className)) {\n el.classList.add(ctx.current.className);\n }\n },\n remove() {\n if (ctx.current.className) el.classList.remove(ctx.current.className);\n },\n downHandler() {\n if (ctx.current.disabledHover) return;\n // 按下后预定时添加\n ctx.timers.push(\n window.setTimeout(() => {\n ctx.add();\n }, ctx.current.startTime),\n );\n },\n upHandler() {\n if (ctx.current.disabledHover) return;\n ctx.timers.push(\n window.setTimeout(() => {\n ctx.remove();\n }, ctx.current.stayTime),\n );\n },\n cancelHandler() {\n // 取消(如滚动、移出)立即移除\n ctx.remove();\n },\n };\n\n // 保存上下文\n // @ts-ignore - 自定义 symbol 属性\n el[CTX_KEY] = ctx;\n\n // pointer 事件优先,兼容性不足时使用 touch\n const hasPointer = 'PointerEvent' in window;\n if (hasPointer) {\n el.addEventListener('pointerdown', ctx.downHandler, { passive: true });\n el.addEventListener('pointerup', ctx.upHandler, { passive: true });\n el.addEventListener('pointercancel', ctx.cancelHandler, { passive: true });\n el.addEventListener('pointerleave', ctx.cancelHandler, { passive: true });\n } else {\n el.addEventListener('touchstart', ctx.downHandler, { passive: true });\n el.addEventListener('touchend', ctx.upHandler, { passive: true });\n el.addEventListener('touchcancel', ctx.cancelHandler, { passive: true });\n el.addEventListener('touchmove', ctx.cancelHandler, { passive: true });\n }\n },\n updated(el, binding) {\n // @ts-ignore\n const ctx: HoverContext | undefined = el[CTX_KEY];\n if (!ctx) return;\n const next = resolveBinding(binding);\n const prev = ctx.current;\n // className 变化需要替换\n if (prev.className !== next.className) {\n if (prev.className) el.classList.remove(prev.className);\n if (!next.disabledHover && next.className && el.matches(':active')) {\n el.classList.add(next.className);\n }\n }\n ctx.current = next;\n },\n unmounted(el) {\n // @ts-ignore\n const ctx: HoverContext | undefined = el[CTX_KEY];\n if (!ctx) return;\n ctx.timers.forEach((t) => window.clearTimeout(t));\n ctx.remove();\n const hasPointer = 'PointerEvent' in window;\n if (hasPointer) {\n el.removeEventListener('pointerdown', ctx.downHandler);\n el.removeEventListener('pointerup', ctx.upHandler);\n el.removeEventListener('pointercancel', ctx.cancelHandler);\n el.removeEventListener('pointerleave', ctx.cancelHandler);\n } else {\n el.removeEventListener('touchstart', ctx.downHandler);\n el.removeEventListener('touchend', ctx.upHandler);\n el.removeEventListener('touchcancel', ctx.cancelHandler);\n el.removeEventListener('touchmove', ctx.cancelHandler);\n }\n // @ts-ignore\n delete el[CTX_KEY];\n },\n};\n\nexport default Hover;\n"],"names":["DEFAULT_DELAY","startTime","stayTime","CTX_KEY","Symbol","resolveBinding","binding","value","className","disabledHover","_binding$value","_binding$value$disabl","_binding$value$startT","_binding$value$stayTi","Hover","created","el","state","ctx","current","timers","add","classList","contains","remove","downHandler","push","window","setTimeout","upHandler","cancelHandler","hasPointer","addEventListener","passive","updated","next","prev","matches","unmounted","forEach","t","clearTimeout","removeEventListener"],"mappings":";;;;;;AA8BA,IAAMA,aAAgB,GAAA;AAAEC,EAAAA,SAAW,EAAA,EAAA;AAAIC,EAAAA,UAAU,EAAA;AAAG,CAAA,CAAA;AACpD,IAAMC,OAAA,GAAyBC,OAAO,SAAS,CAAA,CAAA;AAE/C,SAASC,eAAeC,OAAkE,EAAA;AACpF,EAAA,IAAA,CAACA,QAAQC,KAAO,EAAA;IACX,OAAA;AAAEC,MAAAA,SAAW,EAAA,EAAA;AAAIC,MAAAA,aAAe,EAAA,IAAA;MAAMR,WAAWD,aAAc,CAAAC,SAAA;MAAWC,QAAU,EAAAF,aAAA,CAAcE,QAAAA;KAAS,CAAA;AACpH,GAAA;AACI,EAAA,IAAA,OAAOI,OAAQ,CAAAC,KAAA,KAAU,QAAU,EAAA;IAC9B,OAAA;MACLC,WAAWF,OAAQ,CAAAC,KAAA;AACnBE,MAAAA,aAAe,EAAA,KAAA;MACfR,WAAWD,aAAc,CAAAC,SAAA;MACzBC,UAAUF,aAAc,CAAAE,QAAAA;KAC1B,CAAA;AACF,GAAA;AACM,EAAA,IAAAQ,cAAA,GAKFJ,OAAQ,CAAAC,KAAA;IAJVC,SAAA,GAAAE,cAAA,CAAAF,SAAA;IAAAG,qBAAA,GAAAD,cAAA,CACAD,aAAgB;AAAhBA,IAAAA,aAAgB,GAAAE,qBAAA,KAAA,KAAA,CAAA,GAAA,KAAA,GAAAA,qBAAA;IAAAC,qBAAA,GAAAF,cAAA,CAChBT;AAAAA,IAAAA,+CAAYD,aAAc,CAAAC,SAAA,GAAAW,qBAAA;IAAAC,qBAAA,GAAAH,cAAA,CAC1BR;AAAAA,IAAAA,8CAAWF,aAAc,CAAAE,QAAA,GAAAW,qBAAA,CAAA;EAE3B,OAAO;AAAEL,IAAAA,SAAA,EAAAA,SAAA;AAAWC,IAAAA,aAAe,EAAfA,aAAe;AAAAR,IAAAA,SAAA,EAAAA,SAAA;AAAWC,IAAAA,QAAS,EAATA,QAAAA;GAAS,CAAA;AACzD,CAAA;AAEA,IAAMY,KAA8C,GAAA;AAClDC,EAAAA,OAAA,WAAAA,OAAAA,CAAQC,IAAIV,OAAS,EAAA;AACb,IAAA,IAAAW,KAAA,GAAQZ,eAAeC,OAAO,CAAA,CAAA;AACpC,IAAA,IAAMY,GAAoB,GAAA;AACxBC,MAAAA,OAAS,EAAAF,KAAA;AACTG,MAAAA,QAAQ,EAAC;MACTC,GAAM,EAAA,SAANA,GAAMA,GAAA;AACJ,QAAA,IAAIH,GAAI,CAAAC,OAAA,CAAQV,aAAiB,IAAA,CAACS,IAAIC,OAAQ,CAAAX,SAAA,EAAW,OAAA;AAEzD,QAAA,IAAI,CAACQ,EAAG,CAAAM,SAAA,CAAUC,SAASL,GAAI,CAAAC,OAAA,CAAQX,SAAS,CAAG,EAAA;UACjDQ,EAAA,CAAGM,SAAU,CAAAD,GAAA,CAAIH,GAAI,CAAAC,OAAA,CAAQX,SAAS,CAAA,CAAA;AACxC,SAAA;OACF;MACAgB,MAAS,EAAA,SAATA,MAASA,GAAA;AACP,QAAA,IAAIN,IAAIC,OAAQ,CAAAX,SAAA,EAAWQ,EAAA,CAAGM,SAAU,CAAAE,MAAA,CAAON,GAAI,CAAAC,OAAA,CAAQX,SAAS,CAAA,CAAA;OACtE;MACAiB,WAAc,EAAA,SAAdA,WAAcA,GAAA;AACZ,QAAA,IAAIP,IAAIC,OAAQ,CAAAV,aAAA,EAAe,OAAA;QAE/BS,GAAA,CAAIE,MAAO,CAAAM,IAAA,CACTC,MAAA,CAAOC,WAAW,YAAM;UACtBV,GAAA,CAAIG,GAAI,EAAA,CAAA;AACV,SAAA,EAAGH,GAAI,CAAAC,OAAA,CAAQlB,SAAS,CAC1B,CAAA,CAAA;OACF;MACA4B,SAAY,EAAA,SAAZA,SAAYA,GAAA;AACV,QAAA,IAAIX,IAAIC,OAAQ,CAAAV,aAAA,EAAe,OAAA;QAC/BS,GAAA,CAAIE,MAAO,CAAAM,IAAA,CACTC,MAAA,CAAOC,WAAW,YAAM;UACtBV,GAAA,CAAIM,MAAO,EAAA,CAAA;AACb,SAAA,EAAGN,GAAI,CAAAC,OAAA,CAAQjB,QAAQ,CACzB,CAAA,CAAA;OACF;MACA4B,aAAgB,EAAA,SAAhBA,aAAgBA,GAAA;QAEdZ,GAAA,CAAIM,MAAO,EAAA,CAAA;AACb,OAAA;KACF,CAAA;AAIAR,IAAAA,EAAA,CAAGb,OAAW,CAAA,GAAAe,GAAA,CAAA;AAGd,IAAA,IAAMa,aAAa,cAAkB,IAAAJ,MAAA,CAAA;AACrC,IAAA,IAAII,UAAY,EAAA;MACdf,EAAA,CAAGgB,iBAAiB,aAAe,EAAAd,GAAA,CAAIO,aAAa;AAAEQ,QAAAA,OAAA,EAAS,IAAA;AAAK,OAAC,CAAA,CAAA;MACrEjB,EAAA,CAAGgB,iBAAiB,WAAa,EAAAd,GAAA,CAAIW,WAAW;AAAEI,QAAAA,OAAA,EAAS,IAAA;AAAK,OAAC,CAAA,CAAA;MACjEjB,EAAA,CAAGgB,iBAAiB,eAAiB,EAAAd,GAAA,CAAIY,eAAe;AAAEG,QAAAA,OAAA,EAAS,IAAA;AAAK,OAAC,CAAA,CAAA;MACzEjB,EAAA,CAAGgB,iBAAiB,cAAgB,EAAAd,GAAA,CAAIY,eAAe;AAAEG,QAAAA,OAAA,EAAS,IAAA;AAAK,OAAC,CAAA,CAAA;AAC1E,KAAO,MAAA;MACLjB,EAAA,CAAGgB,iBAAiB,YAAc,EAAAd,GAAA,CAAIO,aAAa;AAAEQ,QAAAA,OAAA,EAAS,IAAA;AAAK,OAAC,CAAA,CAAA;MACpEjB,EAAA,CAAGgB,iBAAiB,UAAY,EAAAd,GAAA,CAAIW,WAAW;AAAEI,QAAAA,OAAA,EAAS,IAAA;AAAK,OAAC,CAAA,CAAA;MAChEjB,EAAA,CAAGgB,iBAAiB,aAAe,EAAAd,GAAA,CAAIY,eAAe;AAAEG,QAAAA,OAAA,EAAS,IAAA;AAAK,OAAC,CAAA,CAAA;MACvEjB,EAAA,CAAGgB,iBAAiB,WAAa,EAAAd,GAAA,CAAIY,eAAe;AAAEG,QAAAA,OAAA,EAAS,IAAA;AAAK,OAAC,CAAA,CAAA;AACvE,KAAA;GACF;AACAC,EAAAA,OAAA,WAAAA,OAAAA,CAAQlB,IAAIV,OAAS,EAAA;AAEnB,IAAA,IAAMY,MAAgCF,EAAG,CAAAb,OAAA,CAAA,CAAA;IACzC,IAAI,CAACe,GAAA,EAAK,OAAA;AACJ,IAAA,IAAAiB,IAAA,GAAO9B,eAAeC,OAAO,CAAA,CAAA;AACnC,IAAA,IAAM8B,OAAOlB,GAAI,CAAAC,OAAA,CAAA;AAEb,IAAA,IAAAiB,IAAA,CAAK5B,SAAc,KAAA2B,IAAA,CAAK3B,SAAW,EAAA;AACrC,MAAA,IAAI4B,IAAK,CAAA5B,SAAA,EAAcQ,EAAA,CAAAM,SAAA,CAAUE,MAAO,CAAAY,IAAA,CAAK5B,SAAS,CAAA,CAAA;AAClD,MAAA,IAAA,CAAC2B,KAAK1B,aAAiB,IAAA0B,IAAA,CAAK3B,aAAaQ,EAAG,CAAAqB,OAAA,CAAQ,SAAS,CAAG,EAAA;QAC/DrB,EAAA,CAAAM,SAAA,CAAUD,GAAI,CAAAc,IAAA,CAAK3B,SAAS,CAAA,CAAA;AACjC,OAAA;AACF,KAAA;IACAU,GAAA,CAAIC,OAAU,GAAAgB,IAAA,CAAA;GAChB;AACAG,EAAAA,WAAAA,SAAAA,UAAUtB,EAAI,EAAA;AAEZ,IAAA,IAAME,MAAgCF,EAAG,CAAAb,OAAA,CAAA,CAAA;IACzC,IAAI,CAACe,GAAA,EAAK,OAAA;AACVA,IAAAA,GAAA,CAAIE,OAAOmB,OAAQ,CAAA,UAACC;aAAMb,MAAO,CAAAc,YAAA,CAAaD,CAAC,CAAC,CAAA;KAAA,CAAA,CAAA;IAChDtB,GAAA,CAAIM,MAAO,EAAA,CAAA;AACX,IAAA,IAAMO,aAAa,cAAkB,IAAAJ,MAAA,CAAA;AACrC,IAAA,IAAII,UAAY,EAAA;MACXf,EAAA,CAAA0B,mBAAA,CAAoB,aAAe,EAAAxB,GAAA,CAAIO,WAAW,CAAA,CAAA;MAClDT,EAAA,CAAA0B,mBAAA,CAAoB,WAAa,EAAAxB,GAAA,CAAIW,SAAS,CAAA,CAAA;MAC9Cb,EAAA,CAAA0B,mBAAA,CAAoB,eAAiB,EAAAxB,GAAA,CAAIY,aAAa,CAAA,CAAA;MACtDd,EAAA,CAAA0B,mBAAA,CAAoB,cAAgB,EAAAxB,GAAA,CAAIY,aAAa,CAAA,CAAA;AAC1D,KAAO,MAAA;MACFd,EAAA,CAAA0B,mBAAA,CAAoB,YAAc,EAAAxB,GAAA,CAAIO,WAAW,CAAA,CAAA;MACjDT,EAAA,CAAA0B,mBAAA,CAAoB,UAAY,EAAAxB,GAAA,CAAIW,SAAS,CAAA,CAAA;MAC7Cb,EAAA,CAAA0B,mBAAA,CAAoB,aAAe,EAAAxB,GAAA,CAAIY,aAAa,CAAA,CAAA;MACpDd,EAAA,CAAA0B,mBAAA,CAAoB,WAAa,EAAAxB,GAAA,CAAIY,aAAa,CAAA,CAAA;AACvD,KAAA;IAEA,OAAOd,EAAG,CAAAb,OAAA,CAAA,CAAA;AACZ,GAAA;AACF;;;;"}