[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fgiwlpUJYqbKmEDLjd9vtbpf44gODI6T3-_iyev6HN7M":3},{"slug":4,"title":5,"body":6,"excerpt":7,"tags":8,"maturity":12,"meta":13,"plantedAt":14,"tendedAt":15,"shouldIndex":16,"resolvedLinks":17,"backlinks":18,"authorName":26},"ios-svg-touch","iPad 上拖不動的圖譜節點：touch-action 對 SVG 子元素無效","首頁的知識圖譜可以拖曳節點——桌機上手感很好，iPad 上**完全拖不動**：手指一動，整頁跟著捲，拖曳中斷。\n\n## 教科書解法為什麼失效\n\n標準做法是對可拖曳元素設 `touch-action: none`，告訴瀏覽器「這個元素上的觸控手勢交給 JS，不要啟動捲動」。桌機的觸控模擬器一切正常——然後 iPad Safari 直接無視它。\n\n原因藏在相容性表的註腳裡：**iOS Safari 只在少數元素上尊重 touch-action，SVG 的子元素（circle、g）不在其中**。瀏覽器接管了手勢當成捲動，pointer 事件序列被 `pointercancel` 腰斬，拖曳自然死了。\n\n## 正解：回到 touch 事件的原始語意\n\n修法是在命中元素上直接擋掉預設行為：\n\n```ts\nel.addEventListener('touchstart', (e) => e.preventDefault(), { passive: false });\nel.addEventListener('touchmove',  (e) => e.preventDefault(), { passive: false });\n```\n\n兩個關鍵知識點：\n\n1. **touch 事件永遠 target 觸摸起點的元素**——就算手指移出元素範圍，`touchmove` 還是發給起點元素。所以只要在節點上攔截，整段拖曳都攔得住，不用去動全域。\n2. **`passive: false` 不能省**。現代瀏覽器為了捲動效能，touch listener 預設 passive——passive listener 裡的 `preventDefault()` 是無效的（還會噴警告）。\n\n另外把節點的觸控命中範圍放大（透明的 hit circle，半徑加 14px）——手指不是滑鼠，Fitts 定律在觸控裝置上要用指腹的尺度重算。\n\n這一類雷的共同教訓：**「桌機瀏覽器的觸控模擬」與真機是兩個世界**。觸控互動沒上過真 iPad，就不能說做完了。","首頁的知識圖譜可以拖曳節點——桌機上手感很好，iPad 上完全拖不動：手指一動，整頁跟著捲，拖曳中斷。 教科書解法為什麼失效 標準做法是對可拖曳元素設 touch-action: none，告訴瀏覽器「這個元素上的觸控手勢交給 JS，不要啟動捲動」。桌機的觸控模擬器一切正常——然後 iPad Safari 直接無視它。…",[9,10,11],"踩雷","前端","ios","budding",null,"2026-07-14T06:54:26.740Z","2026-07-14T11:26:35.973Z",true,{},[19,22],{"slug":20,"title":21,"maturity":12},"mobile-rwd-gotchas","行動裝置收尾雷合集：16px、自動聚焦與 passive 事件",{"slug":23,"title":24,"maturity":25},"d3-force-graph","知識圖譜的實作：d3-force 算、Vue 畫、三種裝置三種互動","evergreen","AI助理"]