如何通过Ref调用lightgallery.js?点击p标签无法打开问题排查
问题:React中点击p标签无法触发lightgallery.js打开
我尝试通过p标签的onClick事件调用lightgallery.js的openGallery()方法,但无法正常生效。以下是我的React组件代码:
const Gallery = ({ className, galleryType, children }: props) => { let lightGalleryRef = useRef<ILightGallery>(null); const onInit = useCallback(() => { }, []); const openGallery = () => { console.log('hit'); lightGalleryRef?.current?.openGallery(); }; return ( <div className={`relative group ${className}`}> {galleryType == 'video' && <Image priority src={'/images/3d-icon.png'} width={150} height={150} alt="hero image example" onClick={openGallery} className='absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer pointer-events-none z-[1] group-hover:opacity-80' />} <LightGallery onInit={onInit} ref={lightGalleryRef} plugins={[lgZoom, lgVideo]} mode="lg-fade" thumbnail={true} hideScrollbar={true} autoplayFirstVideo={galleryType === 'video' ? true : false} youTubePlayerParams={{ autoplay: 1, mute: 1 }} addClass='lightbox-gallery' elementClassNames={galleryType} mobileSettings={{ controls: false, showCloseIcon: false, download: false, rotate: false, }} > {children} </LightGallery> <div className='flex mt-4 cursor-pointer items-center'> <div> <Image src="/images/maximize.png" alt="arrow" width={11} height={11} className="" /> </div> <p className='ml-2 text-brand-light-blue text-sm' onClick={openGallery}>{galleryType === 'gallery' || galleryType === 'gallery-single' ? 'Enlarge and view' : '3D view'}</p> </div> </div> ) } export default Gallery
问题原因
- Ref未正确绑定实例:
lightGalleryRef在LightGallery组件完成初始化前,current值为null。空的onInit回调没有利用初始化时机确认实例状态,导致调用openGallery()时可能实例还未挂载完成。 - 视频图标点击失效(额外问题):视频图标上的
pointer-events-none类会阻止点击事件触发,影响另一处触发入口。
修复方案
修改代码,利用onInit回调跟踪实例就绪状态,确保调用openGallery()时实例已存在:
import { useState, useRef, useCallback } from 'react'; import LightGallery from 'lightgallery/react'; import lgZoom from 'lightgallery/plugins/zoom'; import lgVideo from 'lightgallery/plugins/video'; type props = { className?: string; galleryType: 'video' | 'gallery' | 'gallery-single'; children: React.ReactNode; }; const Gallery = ({ className, galleryType, children }: props) => { const lightGalleryRef = useRef<ILightGallery>(null); const [isGalleryReady, setIsGalleryReady] = useState(false); // 在onInit中确认实例初始化完成并更新状态 const onInit = useCallback((instance: ILightGallery) => { lightGalleryRef.current = instance; setIsGalleryReady(true); }, []); const openGallery = () => { console.log('hit'); // 只有当实例就绪时才调用方法 if (isGalleryReady && lightGalleryRef.current) { lightGalleryRef.current.openGallery(); } }; return ( <div className={`relative group ${className}`}> {galleryType == 'video' && ( <Image priority src={'/images/3d-icon.png'} width={150} height={150} alt="hero image example" onClick={openGallery} className='absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 cursor-pointer z-[1] group-hover:opacity-80' // 移除pointer-events-none,让图标可点击 /> )} <LightGallery onInit={onInit} ref={lightGalleryRef} plugins={[lgZoom, lgVideo]} mode="lg-fade" thumbnail={true} hideScrollbar={true} autoplayFirstVideo={galleryType === 'video'} youTubePlayerParams={{ autoplay: 1, mute: 1 }} addClass='lightbox-gallery' elementClassNames={galleryType} mobileSettings={{ controls: false, showCloseIcon: false, download: false, rotate: false, }} > {children} </LightGallery> <div className='flex mt-4 cursor-pointer items-center'> <div> <Image src="/images/maximize.png" alt="arrow" width={11} height={11} className="" /> </div> <p className='ml-2 text-brand-light-blue text-sm' onClick={openGallery}> {galleryType === 'gallery' || galleryType === 'gallery-single' ? 'Enlarge and view' : '3D view'} </p> </div> </div> ); }; export default Gallery
关键修改点
- 新增
isGalleryReady状态,避免在实例未初始化时调用openGallery()。 - 在
onInit回调中手动绑定实例到ref,并标记状态为就绪,确保ref的有效性。 - 移除视频图标上的
pointer-events-none类,恢复该图标的点击触发能力(如果需要)。 - 简化
autoplayFirstVideo的条件判断,逻辑保持一致。
内容的提问来源于stack exchange,提问作者BennKingy
相关产品推荐
相关产品推荐

