touchMove crashes with "Cannot read properties of null (reading 'offsetWidth')" when the current slide element is not in the DOM
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:
- Initialize in dynamic mode with mode: 'lg-fade' and speed: 0 (config below).
- Open the gallery and start dragging a slide horizontally with the mouse.
- While dragging, the current slide item leaves the DOM (dynamic (re)build / slide change), but the window-bound mousemove keeps calling touchMove.
- 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.
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
<!-- 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