{"id":18056039,"url":"https://github.com/argyleink/scrollend-explainer","last_synced_at":"2025-04-05T09:44:09.575Z","repository":{"id":145673076,"uuid":"575580757","full_name":"argyleink/scrollend-explainer","owner":"argyleink","description":null,"archived":false,"fork":false,"pushed_at":"2023-04-03T22:03:12.000Z","size":4,"stargazers_count":12,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-02T13:30:44.130Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://developer.mozilla.org/en-US/docs/Web/API/Document/scrollend_event","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/argyleink.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-07T20:47:50.000Z","updated_at":"2023-09-21T21:39:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"7ee3c008-bb7a-4efa-b8fd-e988620fb757","html_url":"https://github.com/argyleink/scrollend-explainer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argyleink%2Fscrollend-explainer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argyleink%2Fscrollend-explainer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argyleink%2Fscrollend-explainer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argyleink%2Fscrollend-explainer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/argyleink","download_url":"https://codeload.github.com/argyleink/scrollend-explainer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247318721,"owners_count":20919483,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-31T01:13:23.487Z","updated_at":"2025-04-05T09:44:09.553Z","avatar_url":"https://github.com/argyleink.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"## A `scrollend` Explainer\n\nUpdate April 3, 2023:  \nThis is now on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document/scrollend_event) and shipping in browsers:\n- Firefox 109\n- Chrome 114\n\n### Problem Statement\nWeb developers often watch scroll events to synchronize ancillary elements, fetch data, trigger animations, and more. Today watching scroll events is done with the [`scroll`](https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event) event. But if developers want to know when scroll has ended, or rested and isn't moving anymore, there currently is no event. To work around this, developers set a timeout and/or check scroll positions, to [attempt an estimated scrollend event](https://gomakethings.com/detecting-when-a-visitor-has-stopped-scrolling-with-vanilla-javascript/), like so:\n\n```js\nelement.addEventListener('scroll', () =\u003e {\n  clearTimeout(element.scrollEndTimer);              \n  element.scrollEndTimer = setTimeout(synchronizeFn, 100);\n});\n```\n\nThe fastest this function can determine when scroll has ended is `100ms`. It's also quite wasteful as it overrides the previous timeout on every scroll tick. Browser engines don't like this waste and developers don't like this delay. Furthermore, this strategy will fire `synchronizeFn()` if a user has scrolled with their finger and paused for 100ms, essentially prematurely firing the event because scroll hasn't changed, but the user isn't done.\n\n### Use Cases\n\n#### #1 Scrollable Tabs\n\nhttps://user-images.githubusercontent.com/1134620/206300052-77136c7c-84a4-4ca0-9d13-0b41172c4795.mp4\n\nhttps://codepen.io/argyleink/pen/JjXoXVe\n\n#### #2 Carousel with dots and animation\n\nhttps://user-images.githubusercontent.com/1134620/206300625-7164f650-48e6-43bd-873f-42608cf473ba.mp4\n\nhttps://codepen.io/argyleink/pen/jOzEpjG/e26504e41694bd6267469ba23effae30\n\n#### #3 Determining which element has snapped\n\nhttps://user-images.githubusercontent.com/1134620/206301175-e18fca95-e05e-45ee-aaf4-b15a6f594fab.mp4\n\nhttps://codepen.io/argyleink/pen/wveVPom/17a5b2ee3236403d369881d816b0f03d\n\n### Solution\nA [`scrollend`](https://drafts.csswg.org/cssom-view/#scrolling-events) event that takes into account user interaction, proper timing, and the visual viewport.\n\n```js\nelement.addEventListener('scrollend', () =\u003e {\n  synchronizeFn()\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fargyleink%2Fscrollend-explainer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fargyleink%2Fscrollend-explainer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fargyleink%2Fscrollend-explainer/lists"}