Virtual Scrolling Bug Fixes

Issues Fixed

1. ✅ Row Selection Not Working

Problem: Row selection was not functioning in virtual scrolling mode even when enabled.

Root Cause: Virtual scrolling dynamically renders rows, but the selection manager's event listeners were only attached to the initial DOM elements.

Solution:

Code Changes:

// Event delegation for dynamically rendered rows
setupEventDelegation() {
  this.scrollContainer.addEventListener('click', (event) => {
    const row = event.target.closest('.tablix-row');
    if (!row) return;

    const rowIndex = parseInt(row.getAttribute('data-virtual-index'));
    const rowData = this.data[rowIndex];

    if (rowData) {
      this.table.eventManager.trigger('rowClick', {
        rowData, rowIndex, originalEvent: event, element: row
      });
    }
  });
}

2. ✅ Scrollbar Dragging Issues

Problem: When dragging the scrollbar rapidly, rows would sometimes not render until manual scroll wheel movement.

Root Cause: The throttled scroll handler (16ms delay) was too slow for rapid scrollbar dragging, causing missed scroll events.

Solution:

Code Changes:

// Immediate scroll handling for fast scrolling
handleScrollImmediate() {
  const now = performance.now();
  const scrollTop = this.scrollContainer.scrollTop;

  // Calculate scroll velocity
  if (this.lastScrollTime && this.lastScrollTop !== undefined) {
    const timeDelta = now - this.lastScrollTime;
    const scrollDelta = Math.abs(scrollTop - this.lastScrollTop);
    this.scrollVelocity = timeDelta > 0 ? scrollDelta / timeDelta : 0;
  }

  // For very fast scrolling, schedule immediate update
  if (this.scrollVelocity > 2) {
    this.scheduleUpdate();
  }
}

3. ✅ Image Loading During Fast Scrolling

Problem: Images would sometimes not load or appear broken during rapid scrolling.

Root Cause: Browser image loading was being interrupted by frequent DOM updates during virtual scrolling.

Solution:

Code Changes:

// Optimized image loading
handleImageLoading() {
  const images = this.tableBody.querySelectorAll('.tablix-row img');

  images.forEach(img => {
    if (img.complete || img.classList.contains('loading')) return;

    img.classList.add('loading');
    img.style.opacity = '0.5';
    img.style.transition = 'opacity 0.2s ease';

    const handleLoad = () => {
      img.classList.remove('loading');
      img.style.opacity = '1';
    };

    img.addEventListener('load', handleLoad);
    img.addEventListener('error', handleLoad);
  });
}

Performance Improvements

Testing

Run the bug fix tests:

Verification Steps

  1. Selection Test:

  2. Scrollbar Dragging Test:

  3. Image Loading Test:

Browser Compatibility

Tested and working in:

All fixes maintain backward compatibility with existing TablixJS features.