CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-better-scroll

High-performance mobile scrolling library with smooth scrolling, momentum, bounce effects, and extensive plugin support.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

features.mddocs/

Features & Plugins

Better Scroll's modular architecture provides specialized features through configuration-enabled plugins. Each feature extends the core scrolling functionality with specific capabilities for different use cases.

Capabilities

Snap/Slide Feature

Page-based scrolling with snap-to-position functionality, ideal for carousels, image galleries, and paged content.

interface SnapOptions {
  loop?: boolean;              // Enable infinite loop (default: false)
  threshold?: number;          // Snap threshold (0-1, default: 0.1)
  speed?: number;              // Snap animation speed in ms (default: 400)
  easing?: EasingFunction;     // Snap easing function
  stepX?: number;              // Horizontal step size (default: wrapper width)
  stepY?: number;              // Vertical step size (default: wrapper height)
  el?: HTMLElement | string;   // Snap to specific elements
}

// Methods added when snap enabled
goToPage(x: number, y: number, time?: number, easing?: EasingFunction): void;
next(time?: number, easing?: EasingFunction): void;
prev(time?: number, easing?: EasingFunction): void;
getCurrentPage(): {x: number, y: number, pageX: number, pageY: number} | null;

// Instance properties when snap enabled
currentPage: {
  x: number;                   // Current page X coordinate
  y: number;                   // Current page Y coordinate  
  pageX: number;               // Current page index X
  pageY: number;               // Current page index Y
};
pages: Array<Array<{         // 2D array of page information
  x: number;                 // Page position X
  y: number;                 // Page position Y
  width: number;             // Page width
  height: number;            // Page height
  cx: number;                // Center X
  cy: number;                // Center Y
}>>;

Usage Examples:

// Basic snap scrolling
const scroll = new BScroll('.wrapper', {
  snap: true,
  momentum: false,
  bounce: false
});

// Custom snap configuration
const scroll = new BScroll('.wrapper', {
  snap: {
    loop: true,
    threshold: 0.3,
    speed: 400,
    stepX: 300,
    stepY: 200
  }
});

// Snap to specific elements  
const scroll = new BScroll('.wrapper', {
  snap: {
    el: '.slide-item',
    loop: true
  }
});

// Access current page
console.log('Current page:', scroll.currentPage.pageX, scroll.currentPage.pageY);

// Navigate to specific page
scroll.goToPage(2, 0, 300); // pageX, pageY, duration

Wheel Picker Feature

Wheel-style picker component for selecting items from a list with 3D rotation effects.

interface WheelOptions {
  selectedIndex?: number;      // Initial selected index (default: 0)
  rotate?: number;             // Rotation angle per item in degrees (default: 25)
  adjustTime?: number;         // Animation time for adjustment in ms (default: 400)
  wheelWrapperClass?: string;  // CSS class for wheel wrapper (default: 'wheel-scroll')
  wheelItemClass?: string;     // CSS class for wheel items (default: 'wheel-item')
}

// Methods added when wheel enabled
wheelTo(index: number): void;  // Navigate to specific wheel index
getSelectedIndex(): number | boolean;    // Get currently selected index (returns selectedIndex or false)

// Instance properties when wheel enabled
selectedIndex: number;         // Currently selected item index
items: HTMLElement[];          // Array of wheel item elements

Usage Examples:

// Basic wheel picker
const scroll = new BScroll('.wheel-wrapper', {
  wheel: {
    selectedIndex: 2,
    rotate: 25
  }
});

// Custom wheel configuration
const scroll = new BScroll('.picker', {
  wheel: {
    selectedIndex: 0,
    rotate: 30,
    adjustTime: 300,
    wheelWrapperClass: 'my-wheel',
    wheelItemClass: 'my-wheel-item'
  }
});

// Get selected value
console.log('Selected index:', scroll.selectedIndex);
console.log('Selected item:', scroll.items[scroll.selectedIndex]);

// Programmatically select item
scroll.wheelTo(3); // Select item at index 3

// Get selected index
const selectedIndex = scroll.getSelectedIndex();

Pull-to-Refresh Features

Pull-down refresh and pull-up load functionality with customizable thresholds.

interface PullDownRefreshOptions {
  threshold?: number;          // Pull distance threshold in px (default: 90)
  stop?: number;              // Stop position after pull in px (default: 40)
}

interface PullUpLoadOptions {
  threshold?: number;          // Pull distance threshold in px (default: 50)
}

// Methods added when enabled
/**
 * Complete pull-down refresh action
 * Call after refresh data is loaded
 */
finishPullDown(): void;

/**
 * Complete pull-up load action  
 * Call after more data is loaded
 */
finishPullUp(): void;

/**
 * Dynamically enable/disable pull-down refresh
 */
openPullDown(config?: boolean | PullDownRefreshOptions): void;
closePullDown(): void;

/**
 * Programmatically trigger pull-down refresh
 */
autoPullDownRefresh(): void;

/**
 * Dynamically enable/disable pull-up load
 */
openPullUp(config?: boolean | PullUpLoadOptions): void;
closePullUp(): void;

// Events fired:
// 'pullingDown' - When pull-down threshold reached
// 'pullingUp' - When pull-up threshold reached

Usage Examples:

// Pull-to-refresh setup
const scroll = new BScroll('.wrapper', {
  pullDownRefresh: {
    threshold: 90,
    stop: 40
  },
  pullUpLoad: {
    threshold: 50
  }
});

// Handle pull-down refresh
scroll.on('pullingDown', async () => {
  showRefreshIndicator();
  try {
    await refreshData();
    updateContent();
  } finally {
    hideRefreshIndicator();
    scroll.finishPullDown();
  }
});

// Handle pull-up load more
scroll.on('pullingUp', async () => {
  showLoadingIndicator();
  try {
    const newData = await loadMoreData();
    appendContent(newData);
  } finally {
    hideLoadingIndicator();
    scroll.finishPullUp();
  }
});

Scrollbar Feature

Visual scroll indicators with customizable appearance and behavior.

interface ScrollbarOptions {
  fade?: boolean;              // Auto-fade scrollbar (default: true)
  interactive?: boolean;       // Allow scrollbar interaction (default: false)
}

Usage Examples:

// Basic scrollbar
const scroll = new BScroll('.wrapper', {
  scrollbar: true
});

// Custom scrollbar configuration
const scroll = new BScroll('.wrapper', {
  scrollbar: {
    fade: true,
    interactive: true
  }
});

Mouse Wheel Support

Desktop mouse wheel scrolling support with configurable behavior.

interface MouseWheelOptions {
  speed?: number;              // Scroll speed multiplier (default: 20)
  invert?: boolean;            // Invert scroll direction (default: false)
  easeTime?: number;           // Easing duration in ms (default: 300)
}

Usage Examples:

// Basic mouse wheel support
const scroll = new BScroll('.wrapper', {
  mouseWheel: true
});

// Custom mouse wheel configuration
const scroll = new BScroll('.wrapper', {
  mouseWheel: {
    speed: 20,
    invert: false,
    easeTime: 300
  }
});

Zoom Feature

Pinch-to-zoom functionality with scale limits and smooth transitions.

interface ZoomOptions {
  start?: number;              // Initial zoom scale (default: 1)
  min?: number;                // Minimum zoom scale (default: 1)
  max?: number;                // Maximum zoom scale (default: 4)
}

// Methods added when zoom enabled
/**
 * Zoom to specific scale and position
 * @param scale - Target zoom scale
 * @param x - Target X position  
 * @param y - Target Y position
 * @param time - Animation duration in ms
 */
zoomTo(scale: number, x: number, y: number, time?: number): void;

// Instance properties when zoom enabled
scale: number;                 // Current zoom scale

Usage Examples:

// Basic zoom functionality
const scroll = new BScroll('.wrapper', {
  zoom: {
    start: 1,
    min: 0.5,
    max: 3
  }
});

// Zoom to specific scale and position
scroll.zoomTo(2, 100, 100, 300);

// Get current zoom level
console.log('Current zoom:', scroll.scale);

Infinite Scrolling

Virtual scrolling for large datasets with efficient DOM management.

interface InfinityOptions {
  /**
   * Render function for list items
   * @param item - Data item to render
   * @param div - DOM element to render into
   */
  render(item: any, div: HTMLElement): void;
  
  /**
   * Create tombstone/placeholder elements
   * @returns DOM element for tombstone
   */
  createTombstone(): HTMLElement;
  
  /**
   * Fetch more data when needed
   * @param count - Number of items to fetch
   * @returns Promise resolving to array of data items
   */
  fetch(count: number): Promise<any[]>;
}

Usage Examples:

// Infinite scrolling setup
const scroll = new BScroll('.wrapper', {
  infinity: {
    render(item, div) {
      div.innerHTML = `
        <h3>${item.title}</h3>
        <p>${item.description}</p>
      `;
    },
    
    createTombstone() {
      const tombstone = document.createElement('div');
      tombstone.className = 'tombstone';
      tombstone.innerHTML = '<div class="placeholder"></div>';
      return tombstone;
    },
    
    async fetch(count) {
      const response = await fetch(`/api/items?count=${count}`);
      return response.json();
    }
  }
});

Multi-Feature Configurations

Features can be combined for complex scrolling experiences:

// Gallery with snap and zoom
const gallery = new BScroll('.gallery-wrapper', {
  scrollX: true,
  scrollY: false,
  snap: {
    loop: true,
    stepX: 300
  },
  zoom: {
    start: 1,
    min: 0.5,
    max: 3
  },
  mouseWheel: true
});

// List with pull-to-refresh and scrollbar
const list = new BScroll('.list-wrapper', {
  pullDownRefresh: {
    threshold: 90,
    stop: 40
  },
  pullUpLoad: {
    threshold: 50
  },
  scrollbar: {
    fade: true
  },
  probeType: 2
});

// Picker with multiple wheels
const picker = new BScroll('.picker-wrapper', {
  wheel: {
    selectedIndex: 0,
    rotate: 25,
    wheelItemClass: 'picker-item'
  },
  momentum: false,
  bounce: false
});

Performance Considerations

Feature-Specific Optimizations

// For snap/slide - disable momentum and bounce
const slideScroll = new BScroll('.slides', {
  snap: true,
  momentum: false,
  bounce: false,
  probeType: 0  // No scroll events needed
});

// For infinite scroll - minimal animations
const infiniteScroll = new BScroll('.infinite-list', {
  infinity: { /* config */ },
  useTransition: false,  // Use JS animation for smoother infinite scroll
  probeType: 3          // Real-time events for scroll position tracking
});

// For zoom - hardware acceleration
const zoomScroll = new BScroll('.zoom-container', {
  zoom: { /* config */ },
  HWCompositing: true,   // Enable hardware acceleration
  useTransform: true     // Use CSS transforms
});

Memory Management

// Clean up when switching between features
function switchToInfiniteMode() {
  // Destroy existing instance
  if (currentScroll) {
    currentScroll.destroy();
  }
  
  // Create new instance with different features
  currentScroll = new BScroll('.wrapper', {
    infinity: infinityConfig
  });
}

// Proper cleanup on page unload
window.addEventListener('beforeunload', () => {
  if (scroll) {
    scroll.destroy();
  }
});

docs

core-scrolling.md

events.md

features.md

index.md

tile.json