{"_id":"@shelamkoff/infinite-scroll","_rev":"2-f07acb0f06fa4231fd07f1dd640b1b86","name":"@shelamkoff/infinite-scroll","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@shelamkoff/infinite-scroll","version":"1.0.0","keywords":["javascript","infinite-scroll","intersection-observer","lazy-loading","pagination","load-more","scroll","sentinel","vanilla-js","framework-agnostic","esm","typescript"],"author":{"name":"Shelamkoff"},"license":"MIT","_id":"@shelamkoff/infinite-scroll@1.0.0","maintainers":[{"name":"shelamkoff","email":"inbox.shelamkoff@gmail.com"}],"homepage":"https://shelamkoff.github.io/infinite-scroll/","bugs":{"url":"https://github.com/Shelamkoff/infinite-scroll/issues"},"dist":{"shasum":"e4ab8ea2a21cdde3bc12e6b21c55fbe5303f4c41","tarball":"https://registry.npmjs.org/@shelamkoff/infinite-scroll/-/infinite-scroll-1.0.0.tgz","fileCount":8,"integrity":"sha512-l22kkX1i9GXd0csBk1CLWRBjouth09H4RTUrNIRy7M+aZJqn/WFYxdnmvMPdgw1j5AUlPAezDiU+AMNhbaLVkg==","signatures":[{"sig":"MEUCIA8X3GuHv/SaprEQ4P0FPDLVyD9RMYk4L8wNf8L+qT8jAiEAtomg+h9hIFsYo+Xi8IY6uCFex8PUJ/dBVYxvpaoceFo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":12973},"type":"module","engines":{"node":">=20"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./package.json":"./package.json"},"gitHead":"6b7c698b5ac23bd17b945558e80db528438db993","scripts":{"demo":"node scripts/dev-server.mjs /demo.html","test":"node --test","build":"node scripts/build-package.mjs","prepack":"npm run build","prepublishOnly":"npm test"},"_npmUser":{"name":"shelamkoff","email":"inbox.shelamkoff@gmail.com"},"repository":{"url":"git+https://github.com/Shelamkoff/infinite-scroll.git","type":"git"},"_npmVersion":"11.2.0","description":"Small framework-agnostic infinite scroll controller built on IntersectionObserver with loading guards, error handling, and absolute-layout support","directories":{},"_nodeVersion":"24.9.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/infinite-scroll_1.0.0_1784562914613_0.12857939520610295","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@shelamkoff/infinite-scroll","version":"1.0.1","description":"Small framework-agnostic infinite scroll controller built on IntersectionObserver with loading guards, error handling, and absolute-layout support","type":"module","exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./package.json":"./package.json"},"scripts":{"build":"node scripts/build-package.mjs","demo":"node scripts/dev-server.mjs /demo.html","test":"node --test","prepublishOnly":"npm test","prepack":"npm run build"},"keywords":["javascript","infinite-scroll","intersection-observer","lazy-loading","pagination","load-more","scroll","sentinel","vanilla-js","framework-agnostic","esm","typescript"],"author":{"name":"Shelamkoff"},"engines":{"node":">=20"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Shelamkoff/infinite-scroll.git"},"homepage":"https://shelamkoff.github.io/infinite-scroll/","bugs":{"url":"https://github.com/Shelamkoff/infinite-scroll/issues"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_id":"@shelamkoff/infinite-scroll@1.0.1","gitHead":"c7211beb445c7ab4dec25192f501e3b716db138f","_nodeVersion":"24.9.0","_npmVersion":"11.2.0","dist":{"integrity":"sha512-GKgRuicFe/SkqwcA1SxzAenii+sOhQIs5O4yo4KFTByybfYlsMuAPuxVWc5N6HxoLS7B/Q2hFFq/RtVWLKUHRA==","shasum":"5e0118d8fc360a14b89b5079e579bf0dd914039a","tarball":"https://registry.npmjs.org/@shelamkoff/infinite-scroll/-/infinite-scroll-1.0.1.tgz","fileCount":8,"unpackedSize":14216,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD7D0j28y0GtKG8nszmGQctoV607/So4KWiaef/tCEbsQIgahVnYrp/ClC+STqhWu4deNJiIxg2ciIJ4RyA4QHUd8E="}]},"_npmUser":{"name":"shelamkoff","email":"inbox.shelamkoff@gmail.com"},"directories":{},"maintainers":[{"name":"shelamkoff","email":"inbox.shelamkoff@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/infinite-scroll_1.0.1_1784575756813_0.28947802630376485"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-20T15:55:14.437Z","modified":"2026-07-20T19:29:17.099Z","1.0.0":"2026-07-20T15:55:14.775Z","1.0.1":"2026-07-20T19:29:16.945Z"},"bugs":{"url":"https://github.com/Shelamkoff/infinite-scroll/issues"},"author":{"name":"Shelamkoff"},"license":"MIT","homepage":"https://shelamkoff.github.io/infinite-scroll/","keywords":["javascript","infinite-scroll","intersection-observer","lazy-loading","pagination","load-more","scroll","sentinel","vanilla-js","framework-agnostic","esm","typescript"],"repository":{"type":"git","url":"git+https://github.com/Shelamkoff/infinite-scroll.git"},"description":"Small framework-agnostic infinite scroll controller built on IntersectionObserver with loading guards, error handling, and absolute-layout support","maintainers":[{"name":"shelamkoff","email":"inbox.shelamkoff@gmail.com"}],"readme":"# @shelamkoff/infinite-scroll\n\nКомпактный infinite scroll без привязки к фреймворку. Контроллер использует\n`IntersectionObserver`, добавляет один sentinel-элемент, не допускает\nпараллельных загрузок и поддерживает контейнеры с абсолютным позиционированием.\n\n[Демо](https://shelamkoff.github.io/infinite-scroll/) ·\n[English](README.md)\n\n## Возможности\n\n- Без обработчика события `scroll`\n- Только одна активная загрузка\n- Sentinel автоматически переносится после добавленного контента\n- Настраиваемое расстояние предварительной загрузки\n- Пауза и возобновление\n- Обработка ошибок callback\n- Ручное позиционирование sentinel для masonry-layout\n- ESM и TypeScript declarations\n- Без runtime-зависимостей\n\n## Установка\n\n```bash\nnpm install @shelamkoff/infinite-scroll\n```\n\n## Быстрый старт\n\n```js\nimport { InfiniteScroll } from '@shelamkoff/infinite-scroll'\n\nconst feed = document.querySelector('.feed')\n\nconst infiniteScroll = new InfiniteScroll(feed, async () => {\n  const items = await fetchNextPage()\n  appendItems(feed, items)\n}, {\n  threshold: 400,\n  onError(error) {\n    showRetryMessage(error)\n  },\n})\n```\n\nПока callback выполняется, повторные пересечения игнорируются. На одно\nпересечение observer приходится один callback, поэтому видимый sentinel не\nсоздаёт бесконечный цикл запросов. Верните `false`, когда список закончился:\n\n```js\nconst infiniteScroll = new InfiniteScroll(feed, async () => {\n  const page = await fetchNextPage()\n  appendItems(feed, page.items)\n  return page.hasMore\n})\n```\n\n## API\n\n### `new InfiniteScroll(container, callback, options?)`\n\n| Параметр | Тип | По умолчанию | Назначение |\n| --- | --- | --- | --- |\n| `threshold` | `number` | `200` | Отступ предварительной загрузки в пикселях |\n| `sentinel` | `string` | `infinite-scroll-sentinel` | CSS-класс созданного sentinel |\n| `onError` | `(error: unknown) => void` | вывод в console | Получает ошибки callback |\n\nБраузер должен поддерживать `IntersectionObserver`.\n\n### `setLoading(value)`\n\n`true` ставит загрузку на паузу, `false` возобновляет её.\n\nВозврат `false` из load callback использует то же состояние паузы. Вызывайте\n`setLoading(false)` только если позже появились новые данные.\n\n### `updateSentinelPosition(top)`\n\nПосле расчёта абсолютного layout передайте высоту контейнера:\n\n```js\ninfiniteScroll.updateSentinelPosition(containerHeight)\n```\n\n### `destroy()`\n\nОтключает observer и удаляет sentinel. Повторный вызов безопасен. Остальные\nметоды после уничтожения экземпляра выбрасывают ошибку.\n\n## Разработка\n\n```bash\nnpm test\nnpm run build\nnpm run demo\n```\n\n## Лицензия\n\nMIT\n","readmeFilename":"README.ru.md"}