如何避免拖拽绑定Lity的图片时触发Lity灯箱效果?
解决拖拽滑块时误触发Lity灯箱的问题
核心问题是拖拽操作的mouseup事件被Lity识别为点击事件,需要区分点击和拖拽两种操作,仅在纯点击时触发Lity。以下是几种可行的解决方案:
方案1:利用滑块库的拖拽状态事件(优先推荐)
如果你的滑块库提供了拖拽开始/结束的事件(比如Swiper的拖拽事件、Slick的自定义拖拽钩子),直接通过这些事件标记拖拽状态,阻止拖拽时的Lity触发:
const slider = document.querySelector('.small-slider__slider'); // 监听拖拽开始,添加拖拽状态类 slider.addEventListener('dragStart', () => { slider.classList.add('is-dragging'); }); // 监听拖拽结束,移除拖拽状态类 slider.addEventListener('dragEnd', () => { slider.classList.remove('is-dragging'); }); // 在捕获阶段拦截点击,阻止拖拽状态下的Lity触发 document.addEventListener('click', (e) => { if (e.target.closest('.small-slider__slider.is-dragging')) { e.preventDefault(); e.stopPropagation(); } }, true);
方案2:手动追踪拖拽状态(通用方案)
如果滑块库没有提供拖拽事件,通过监听鼠标事件判断用户是否在拖拽:
let isDragging = false; let startX = 0; const slider = document.querySelector('.small-slider__slider'); // 记录鼠标按下的初始位置 slider.addEventListener('mousedown', (e) => { isDragging = false; startX = e.clientX; }); // 鼠标移动超过5像素则判定为拖拽 slider.addEventListener('mousemove', (e) => { if (Math.abs(e.clientX - startX) > 5) { isDragging = true; } }); // 鼠标松开时,若为拖拽则阻止Lity触发 document.addEventListener('mouseup', (e) => { if (isDragging && e.target.closest('.small-slider__item a[data-lity]')) { e.preventDefault(); e.stopPropagation(); } isDragging = false; }, true);
方案3:手动绑定Lity触发逻辑(完全控制)
移除HTML中的data-lity属性,通过JS手动控制Lity的触发时机,仅在非拖拽状态下调用Lity:
修改HTML(去掉data-lity)
<div class="small-slider__slider"> <?php foreach ( $args['screenshots'] as $screenshot ) : ?> <article class="small-slider__item"> <div class="post__image"> <?php if ( ! empty( $src_low_res ) || ! empty( $src_high_res ) ) : ?> <a href="<?php echo esc_url( $src_high_res ); ?>"> <img loading="lazy" src="<?php echo esc_url( $src_low_res ); ?>" alt="<?php echo esc_attr( $alt ); ?>"> </a> <?php endif; ?> </div> </article> <?php endforeach; ?> </div>
添加JS逻辑
let isDragging = false; let startX = 0; const slider = document.querySelector('.small-slider__slider'); slider.addEventListener('mousedown', (e) => { isDragging = false; startX = e.clientX; }); slider.addEventListener('mousemove', (e) => { if (Math.abs(e.clientX - startX) > 5) { isDragging = true; } }); // 仅在非拖拽时触发Lity slider.addEventListener('click', (e) => { const link = e.target.closest('a'); if (link && !isDragging) { e.preventDefault(); lity(link.getAttribute('href')); } });
关键说明
- 拖拽判定的像素阈值(比如5px)可以根据实际需求调整,太小可能误判,太大可能漏判;
- 使用事件捕获阶段(
addEventListener第三个参数设为true)确保拦截逻辑优先于Lity的事件监听; - 方案3最灵活,完全掌控Lity的触发条件,适合对自定义性要求高的场景。
内容的提问来源于stack exchange,提问作者Adriana Hernández
相关产品推荐
相关产品推荐

