// input.js — 输入检测 // 只保留两种操作:单击 / 双击 // 键盘:空格=单击,回车=双击(桌面调试) class InputDetector { constructor(el) { this.el = el; this.onTap = null; this.onDoubleTap = null; this.enabled = false; this._last = 0; this._timer = null; this._WIN = 300; // ms双击判定窗口 this._bindTouch(); this._bindMouse(); this._bindKeyboard(); } enable() { this.enabled = true; } disable() { this.enabled = false; } _fire(e) { e.preventDefault(); if (!this.enabled) return; const now = Date.now(); if (now - this._last < this._WIN) { // 双击 clearTimeout(this._timer); this._last = 0; Haptic.confirm(); SFX_UI.skip(); dbg('[input] double-tap'); if (this.onDoubleTap) this.onDoubleTap(); } else { this._last = now; this._timer = setTimeout(() => { this._last = 0; Haptic.confirm(); SFX_UI.tap(); dbg('[input] tap'); if (this.onTap) this.onTap(); }, this._WIN); } } _bindTouch() { this.el.addEventListener('touchend', e => this._fire(e), { passive: false }); } _bindMouse() { this.el.addEventListener('click', e => this._fire(e)); } _bindKeyboard() { document.addEventListener('keydown', e => { if (!this.enabled) return; if (e.code === 'Space') { e.preventDefault(); Haptic.confirm(); SFX_UI.tap(); dbg('[input] tap (kbd)'); if (this.onTap) this.onTap(); } else if (e.code === 'Enter') { e.preventDefault(); Haptic.confirm(); SFX_UI.skip(); dbg('[input] double-tap (kbd)'); if (this.onDoubleTap) this.onDoubleTap(); } }); } }