使用react-slick轮播时useRef无法调用pause暂停视频如何解决
问题根因
- 你开启了react-slick的
infinite: true配置,该模式下slick会自动复制首尾的slide节点实现无缝滚动效果,你通过单个useRef只能绑定到原始的video节点,无法绑定到复制生成的video节点,所以调用pause方法时操作的不是当前页面正在渲染的节点,自然不会生效。 - 单个ref的写法也不支持后续扩展多个视频slide的场景,复用性低。
解决方案
推荐放弃单个ref绑定的方案,直接在轮播切换时限定范围查找对应视频元素操作即可,修改后的代码如下:
import React, { useRef } from "react"; import Slider from "react-slick"; import "slick-carousel/slick/slick.css"; import "slick-carousel/slick/slick-theme.css"; import "./styles.css"; export default function App() { // 给Slider加ref限定DOM查找范围 const sliderRef = useRef<Slider>(null); const slideAfterChange = (current: number) => { console.log("after change", current); // 仅在当前轮播组件内部查找视频,避免影响页面其他位置的视频 const sliderDom = sliderRef.current?.innerSlider?.list as HTMLElement; if (!sliderDom) return; const allVideos = sliderDom.querySelectorAll<HTMLVideoElement>('video'); if (current === 0) { // 切到视频slide时按需调用播放 allVideos.forEach(video => video.play?.()); } else { // 切到其他slide时暂停所有视频 allVideos.forEach(video => video.pause?.()); } }; const sliderSettings = { dots: true, infinite: true, autoplay: true, autoplaySpeed: 3000, speed: 1000, slidesToShow: 1, slidesToScroll: 1, afterChange: (currentSlide: number) => slideAfterChange(currentSlide) }; return ( <div className="App"> <h1>Slider</h1> <Slider ref={sliderRef} {...sliderSettings}> <div> <video controls width="100%" height="100%"> <source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4" ></source> </video> </div> <div> <img src="http://placekitten.com/g/400/200" alt="示例图" /> </div> </Slider> </div> ); }
如果不需要无缝滚动效果,也可以直接把infinite设为false,原有单个ref绑定的写法也能正常生效。如果后续有多个视频slide的需求,可以把每个视频slide封装为独立组件,内部维护自己的video ref,通过事件通知父组件触发播放/暂停操作即可。
内容的提问来源于stack exchange,提问作者Zagano
相关产品推荐
相关产品推荐

