Sadrazam – Infinite Scroll

Scroll-driven content loading with AJAX pagination

Live Demo

Scroll down inside the container to trigger loading of new items. This demo uses a mock data source instead of a real AJAX endpoint.

    Status: Active — Page 1

    Constructor Options

    Configuration object passed to new Sadrazam.InfiniteScroll({ ... })

    Option Type Required Default Description
    scrollElement Element | Window Yes null The element whose scroll event is listened to. Can be window or any scrollable DOM element (e.g. a <div> with overflow).
    listElement Element Yes null The container element where new items are appended (e.g. a <ul> or <div>).
    source String Yes null The AJAX endpoint URL that returns paginated JSON data.
    startPage Number No 1 The initial page number to start fetching from.
    setInnerItem Function Yes () => {} A callback receiving each data item; must return a DOM element (e.g. <li>) to be appended to the list.

    Expected Response Format

    The AJAX endpoint must return JSON in this shape. The component sends { page: N } as request data.

    // GET /api/items?page=2
    {
      "items": [              // Array of data objects
        { "id": 21, "title": "Item 21" },
        { "id": 22, "title": "Item 22" },
        ...
      ],
      "last": 40,              // Index/count of the last item returned
      "limit": 100             // Total number of items (0 = unlimited)
    }

    Stop When Items array is empty or last >= limit (when limit > 0)
    On Error Scroll listener is paused and no further requests are made

    Basic Usage

    Minimal setup to get infinite scroll working with a scrollable container

    const scroller = new Sadrazam.InfiniteScroll({
      scrollElement: document.getElementById('myScrollContainer'),
      listElement:   document.getElementById('myList'),
      source:        '/api/products',
      startPage:     1,
      setInnerItem:  (item) => {
        const li = document.createElement('li');
        li.textContent = item.title;
        return li;
      }
    });

    Window-Level Scroll

    Use window as the scroll element for full-page infinite scrolling

    const pageScroller = new Sadrazam.InfiniteScroll({
      scrollElement: window,               // Listen on the window object
      listElement:   document.querySelector('.feed'),
      source:        '/api/feed',
      setInnerItem:  (post) => {
        const article = document.createElement('article');
        article.innerHTML = `<h3>${post.title}</h3><p>${post.body}</p>`;
        return article;
      }
    });

    Public API Methods

    Instance methods available after construction

    pause() Removes scroll and touchmove event listeners, stopping further fetch attempts.
    scroller.pause()

    resume() Re-attaches scroll and touchmove listeners. Prevents duplicate listeners internally.
    scroller.resume()

    reCalculate() Manually triggers a scroll check. Useful after external DOM changes that may have altered the scroll position.
    scroller.reCalculate()

    destroy() Fully cleans up: removes listeners, clears throttle timer, removes spinner, and nullifies the listElement.__infiniteScroll reference.
    scroller.destroy()

    Static Properties

    Class-level settings that affect all instances

    throttleTime Minimum interval (ms) between scroll checks. Default: 200
    Sadrazam.InfiniteScroll.throttleTime = 300

    launchDistance Pixel threshold from the bottom of the list to trigger loading. Default: 20
    Sadrazam.InfiniteScroll.launchDistance = 50

    help() Prints all available configuration options with descriptions to the console.
    Sadrazam.InfiniteScroll.help()

    Internal Behavior

    How the component works under the hood

    Spinner A .spinner-block element is automatically created and appended after the list element's parent. It toggles visibility during loading.

    Throttling Scroll events are throttled using setTimeout at InfiniteScroll.throttleTime ms intervals to avoid excessive AJAX calls.

    Auto-fill After each fetch completes, the component uses requestAnimationFrame to re-check scroll position. If content does not fill the container, it fetches again.

    Reference The instance is stored on the list element as listElement.__infiniteScroll for external access.

    Pagination The internal page counter starts at startPage and increments by 1 after each successful append.

    Full Example with Cleanup

    A complete pattern showing initialization, pause/resume controls, and teardown

    const container = document.getElementById('feed-wrapper');
    const list      = document.getElementById('feed-list');
    
    // Initialize
    const feed = new Sadrazam.InfiniteScroll({
      scrollElement: container,
      listElement:   list,
      source:        '/api/posts',
      startPage:     1,
      setInnerItem:  (post) => {
        const li = document.createElement('li');
        li.className = 'post-item';
        li.innerHTML = `
          <strong>${post.title}</strong>
          <p>${post.excerpt}</p>
        `;
        return li;
      }
    });
    
    // Pause when user opens a modal
    modal.on('open', () => feed.pause());
    modal.on('close', () => feed.resume());
    
    // Full teardown on page navigation
    function cleanup() {
      feed.destroy();
      // list.__infiniteScroll is now null
    }
    
    // Access instance from the DOM element
    const ref = list.__infiniteScroll;  // same as `feed`
    ref.reCalculate();