|
181 | 181 | const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0; |
182 | 182 | if (!isTouchDevice) return; |
183 | 183 |
|
| 184 | + // Update hover hints for touch devices |
| 185 | + document.querySelectorAll('.hover-hint').forEach(hint => { |
| 186 | + hint.textContent = '👆 tap or swipe →'; |
| 187 | + }); |
| 188 | + |
184 | 189 | document.querySelectorAll('.tip-card').forEach(card => { |
| 190 | + let touchStartX = 0; |
| 191 | + let touchStartY = 0; |
| 192 | + let touchEndX = 0; |
| 193 | + let touchEndY = 0; |
| 194 | + |
| 195 | + // Track touch start |
| 196 | + card.addEventListener('touchstart', (e) => { |
| 197 | + // Only track touches on the card-code area |
| 198 | + if (!e.target.closest('.card-code')) return; |
| 199 | + |
| 200 | + touchStartX = e.changedTouches[0].clientX; |
| 201 | + touchStartY = e.changedTouches[0].clientY; |
| 202 | + }, { passive: true }); |
| 203 | + |
| 204 | + // Handle touch end for swipe or tap |
| 205 | + // Note: passive:false allows us to preventDefault on tap/swipe while still allowing vertical scrolling |
| 206 | + card.addEventListener('touchend', (e) => { |
| 207 | + // Only handle touches on the card-code area |
| 208 | + if (!e.target.closest('.card-code')) return; |
| 209 | + |
| 210 | + touchEndX = e.changedTouches[0].clientX; |
| 211 | + touchEndY = e.changedTouches[0].clientY; |
| 212 | + |
| 213 | + const deltaX = touchEndX - touchStartX; |
| 214 | + const deltaY = touchEndY - touchStartY; |
| 215 | + const absDeltaX = Math.abs(deltaX); |
| 216 | + const absDeltaY = Math.abs(deltaY); |
| 217 | + |
| 218 | + // Determine if it's a swipe (horizontal movement > 50px and more horizontal than vertical) |
| 219 | + const isHorizontalSwipe = absDeltaX > 50 && absDeltaX > absDeltaY; |
| 220 | + |
| 221 | + if (isHorizontalSwipe) { |
| 222 | + // Prevent default navigation for horizontal swipes |
| 223 | + e.preventDefault(); |
| 224 | + // Swipe left = show modern, swipe right = show old |
| 225 | + if (deltaX < 0) { |
| 226 | + // Swipe left - show modern |
| 227 | + card.classList.add('toggled'); |
| 228 | + } else { |
| 229 | + // Swipe right - show old |
| 230 | + card.classList.remove('toggled'); |
| 231 | + } |
| 232 | + } else if (absDeltaX < 10 && absDeltaY < 10) { |
| 233 | + // It's a tap (movement under 10px threshold) |
| 234 | + e.preventDefault(); |
| 235 | + card.classList.toggle('toggled'); |
| 236 | + } |
| 237 | + // Note: Vertical scrolling (large deltaY, small deltaX) doesn't call preventDefault |
| 238 | + }, { passive: false }); |
| 239 | + |
| 240 | + // Prevent click events on card-code from navigating (touch devices only) |
| 241 | + // This is a safety net in case touch events trigger click as fallback |
185 | 242 | card.addEventListener('click', (e) => { |
186 | | - // Don't toggle if clicking a link inside the card |
187 | | - if (e.target.closest('a')) return; |
188 | | - card.classList.toggle('toggled'); |
| 243 | + if (e.target.closest('.card-code')) { |
| 244 | + e.preventDefault(); |
| 245 | + e.stopPropagation(); |
| 246 | + } |
189 | 247 | }); |
190 | 248 | }); |
191 | 249 | }; |
|
0 commit comments