|
| 1 | +--- |
| 2 | +title: "why click events do not work on iOS" |
| 3 | +tags: ["ios", "html", "javascript"] |
| 4 | +eleventyNavigation: |
| 5 | + key: "ios-event-bubbling" |
| 6 | +keywords: ["ios", "html", "javascript", "event bubbling", "event delegation", "event propagation", "event handling"] |
| 7 | +--- |
| 8 | + |
| 9 | +recently, while preparing the 22.0 release of this website, I noticed that the |
| 10 | +click events on the index page were not working on Apple devices, and as |
| 11 | +such the navigation flow was completely broken. This issue was not present on |
| 12 | +any other platform that I tested, including other mobile devices and desktop |
| 13 | +browsers. |
| 14 | + |
| 15 | +after some quick searches and tests, I found out that the issue was related to |
| 16 | +the way iOS handles click events, and it is a known "bug" that has been around |
| 17 | +for a while. The problem is that iOS does not handle click events as expected, |
| 18 | +and as such, the event delegation mechanism that works on other platforms does |
| 19 | +not work on iOS. |
| 20 | + |
| 21 | +the issue is related to the way iOS handles the `click` event, and it is |
| 22 | +documented in the [Apple Developer Documentation](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html). |
| 23 | + |
| 24 | +here is the *"offending"* code that was causing the issue: |
| 25 | + |
| 26 | +```javascript |
| 27 | +sections.forEach(({ button, section }) => { |
| 28 | + window.addEventListener('click', (event) => { /* ... */ }); |
| 29 | +}); |
| 30 | +``` |
| 31 | + |
| 32 | +after some investigation (and Claude's help), I found out that the issue was |
| 33 | +related to [*event bubbling*](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_bubbling_and_capture). By simply moving the event listener from the |
| 34 | +`window` object to the `document` object and flipping the loop to iterate over |
| 35 | +the sections last, the issue was fixed. |
| 36 | + |
| 37 | +here is the updated code that works on all platforms: |
| 38 | + |
| 39 | +```javascript |
| 40 | +document.addEventListener('click', (event) => { |
| 41 | + sections.forEach(({ button, section }) => { /* ... */ }); |
| 42 | +}); |
| 43 | +``` |
| 44 | + |
| 45 | +Claude also suggested some other changes to the code, such as introducing |
| 46 | +`preventDefault()` for certain events, using `touchend` along with `click` for |
| 47 | +better compatibility, and the mentioned change of the loop order, avoiding the |
| 48 | +addition of separate event listeners. |
| 49 | + |
| 50 | +*Thanks, Claude!* |
| 51 | + |
| 52 | +<br> |
| 53 | + |
| 54 | +### references |
| 55 | + |
| 56 | +- [Apple Developer Documentation](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html) |
| 57 | +- [MDN: Event Bubbling and Capture](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_bubbling_and_capture) |
| 58 | +- [QuircksMode: Click event delegation on iOS](https://www.quirksmode.org/blog/archives/2010/09/click_event_delegation.html) |
| 59 | +- [SitePoint: Handling .click() in the Safari browser](https://www.sitepoint.com/community/t/handling-click-in-the-safari-browser/417837) |
0 commit comments