react+vite+ts滑动标题显示不同视频页面

数据

图片部分与标题部分封装出去

判断图片状态设置index值以便可以滑动切换不同视频内容

渲染视频上去

鼠标移入视频播放 移出暂停

import React, { useRef, useCallback } from 'react';

// 定义视频画廊的属性接口
interface VideoGalleryProps {
    videos: string[]; // 视频源数组
}

// 创建视频画廊组件
const VideoGallery: React.FC<VideoGalleryProps> = ({ videos }) => {
    // 创建引用,分别用于主视频和其他视频
    const mainVideoRef = useRef<HTMLVideoElement | null>(null);
    const videoRefs = useRef<(HTMLVideoElement | null)[]>([]);

    // 鼠标悬停处理函数,播放视频
    const handleMouseEnter = useCallback((index: number) => {
        if (videoRefs.current[index]) {
            videoRefs.current[index]?.play(); // 播放当前视频
        }
        if (index === 0 && mainVideoRef.current) {
            mainVideoRef.current.play(); // 播放主视频
        }
    }, []);

    // 鼠标离开处理函数,暂停视频
    const handleMouseLeave = useCallback((index: number) => {
        if (videoRefs.current[index]) {
            videoRefs.current[index]?.pause(); // 暂停当前视频
        }
        if (index === 0 && mainVideoRef.current) {
            mainVideoRef.current.pause(); // 暂停主视频
        }
    }, []);

    return (
        <div className='focus_bottom_shi'> {/* 整个视频画廊容器 */}
            <div className='img_left'> {/* 主视频区域 */}
                <video 
                    controls // 启用控制条
                    ref={mainVideoRef} // 设置引用
                    onMouseEnter={() => handleMouseEnter(0)} // 鼠标悬停时播放
                    onMouseLeave={() => handleMouseLeave(0)} // 鼠标离开时暂停
                >
                    <source src={videos[0]} type="video/mp4" /> {/* 主视频源 */}
                </video>
            </div>
            <div className='img_right'> {/* 其他视频区域 */}
                {videos.slice(1).map((src, index) => ( // 从第二个视频开始遍历
                    <div
                        key={index} // 唯一键值
                        onMouseEnter={() => handleMouseEnter(index + 1)} // 鼠标悬停时播放
                        onMouseLeave={() => handleMouseLeave(index + 1)} // 鼠标离开时暂停
                    >
                        <video
                            ref={el => videoRefs.current[index + 1] = el} // 设置引用
                            width="150" // 设置视频宽度
                            muted // 静音
                        >
                            <source src={src} type="video/mp4" key={index}/> {/* 视频源 */}
                        </video>
                    </div>
                ))}
            </div>
        </div>
    );
};

// 导出组件
export default VideoGallery;

标题部分代码

import React from 'react';

// 定义接口,描述组件的属性类型
interface SectionListProps {
    sections: string[]; // 字符串数组,表示所有章节的名称
    activeSection: string; // 当前活动章节的名称
    onSectionMouseEnter: (section: string) => void; // 鼠标进入章节时的回调函数
}

// 定义SectionList组件,接收SectionListProps类型的属性
const SectionList: React.FC<SectionListProps> = ({ sections, activeSection, onSectionMouseEnter }) => (
    <ul> {/* 无序列表容器 */}
        {sections.map((section) => ( // 遍历所有章节
            <li
                key={section} // 使用章节名称作为唯一键
                className={`section ${activeSection === section ? 'active' : ''}`} // 根据activeSection决定是否添加active类
                onMouseEnter={() => onSectionMouseEnter(section)} // 鼠标进入时调用回调函数
            >
                {section} {/* 显示章节名称 */}
            </li>
        ))}
    </ul>
);

export default SectionList; 

如果是图片渲染标签就是图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值