touchMove crashes with "Cannot read properties of null (reading 'offsetWidth')" when the current slide element is not in the DOM

Author: zemkogabor2Created Jul 27, 2026Updated Jul 27, 2026

Description

touchMove throws TypeError: Cannot read properties of null (reading 'offsetWidth') when the current slide element isn't in the DOM at the moment of a drag/swipe.

Note that on desktop this is reached via mouse drag, not touch: the enableDrag handler binds mousemove on window and calls touchMove (lib/lightgallery.js, ~line 1446), and the touch enableSwipe handler calls it too (~line 1384). In touchMove the current slide width is read unconditionally:

  const $currentSlide = this.getSlideItem(this.index);
  if (this.swipeDirection === 'horizontal') {
      e?.preventDefault();
      this.outer.addClass('lg-dragging');
      this.setTranslate($currentSlide, distanceX, 0);
      const width = $currentSlide.get().offsetWidth; //  $currentSlide.get() is null
      ...
  }

Steps to reproduce

Timing/race condition, so intermittent rather than 100% reproducible, but it shows up consistently in our error tracking. Captured on desktop (macOS + Chrome) via mouse drag:

  1. Initialize in dynamic mode with mode: 'lg-fade' and speed: 0 (config below).
  2. Open the gallery and start dragging a slide horizontally with the mouse.
  3. While dragging, the current slide item leaves the DOM (dynamic (re)build / slide change), but the window-bound mousemove keeps calling touchMove.
  4. getSlideItem(this.index).get() returns null → TypeError on .offsetWidth.

(No public demo, it happens on an internal admin page. Can provide more detail from the captured events.)

JS code that you use to initialize lightGallery.

javascript
  lightGallery(container, {
      speed: 0,
      mode: 'lg-fade',
      slideEndAnimation: false,
      closeOnTap: false,
      startAnimationDuration: 0,
      startClass: '',
      preload: 4,
      mousewheel: true,
      actualSize: false,
      showZoomInOutIcons: true,
      infiniteZoom: true,
      plugins: [lgThumbnail, lgZoom, lgFullscreen, lgRotate],
      dynamic: true,
      dynamicEl: [
          { src: 'img/img1.jpg', thumb: 'img/thumb1.jpg', subHtml: '' },
          { src: 'img/img2.jpg', thumb: 'img/thumb2.jpg', subHtml: '' },
          // ...
      ],
      escKey: false,
      licenseKey: '1',
      flipHorizontal: false,
      flipVertical: false,
      download: false,
      mobileSettings: {
          showCloseIcon: true,
          download: false,
          rotate: false,
      },
  });

Sample HTML markup

xml
  <!-- dynamic mode: items are provided via dynamicEl, the container is empty -->
  <div id="lightgallery"></div>

Environment

  • Browser and version - Chrome 150 (desktop)
  • OS - macOS (Mac OS X >= 10.15.7)
  • lightGallery version - 2.8.3 (the offending line is unchanged in 2.9.0 as well)

Additional context

  • Reproduced on desktop via mouse drag (enableDrag); the same code path is also reachable via touch swipe (enableSwipe).
  • User-facing impact is negligible (at worst one stuttering drag frame; navigation still completes on mouseup/touchend), but it produces recurring uncaught exceptions in our error tracking.
  • The mousemove drag listener is bound to window, so it keeps invoking touchMove after the drag starts even if the current slide element is removed/replaced.

Source: sachinchoolur/lightGallery