<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>响应式拖拽滑动带缩略图相册</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background-color: #f5f5f5;
padding: 20px;
}
.gallery-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background-color: white;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
}
h1 {
text-align: center;
margin-bottom: 30px;
color: #333;
}
.main-slider {
position: relative;
width: 100%;
height: 500px;
overflow: hidden;
border-radius: 8px;
margin-bottom: 20px;
}
@media (max-width: 768px) {
.main-slider {
height: 300px;
}
}
.main-slide {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 0.5s ease;
display: flex;
align-items: center;
justify-content: center;
}
.main-slide.active {
opacity: 1;
}
.main-slide img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
cursor: grab;
user-select: none;
}
.main-slide img:active {
cursor: grabbing;
}
.thumbnails-container {
width: 100%;
overflow-x: auto;
padding: 10px 0;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE and Edge */
}
.thumbnails-container::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera */
}
.thumbnails {
display: flex;
gap: 10px;
width: max-content;
padding: 0 10px;
}
.thumbnail {
width: 120px;
height: 80px;
border-radius: 5px;
overflow: hidden;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease;
flex-shrink: 0;
position: relative;
}
.thumbnail:hover {
transform: scale(1.05);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
.thumbnail.active {
border: 3px solid #3498db;
transform: scale(1.05);
}
.thumbnail img {
width: 100%;
height: 100%;
object-fit: cover;
}
.navigation {
display: flex;
justify-content: center;
margin-top: 20px;
gap: 15px;
}
.nav-btn {
padding: 10px 20px;
background-color: #3498db;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.nav-btn:hover {
background-color: #2980b9;
}
.nav-btn:disabled {
background-color: #95a5a6;
cursor: not-allowed;
}
.drag-info {
text-align: center;
margin-top: 10px;
color: #7f8c8d;
font-size: 14px;
}
/* 拖拽指示器 */
.drag-indicator {
position: absolute;
top: 10px;
right: 10px;
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 5px 10px;
border-radius: 20px;
font-size: 12px;
display: none;
}
</style>
</head>
<body>
<div class="gallery-container">
<h1>响应式拖拽滑动相册</h1>
<div class="main-slider">
<div class="main-slide active">
<img src="https://picsum.photos/1200/800?random=1" alt="Image 1" draggable="false">
<div class="drag-indicator">拖拽查看</div>
</div>
<div class="main-slide">
<img src="https://picsum.photos/1200/800?random=2" alt="Image 2" draggable="false">
<div class="drag-indicator">拖拽查看</div>
</div>
<div class="main-slide">
<img src="https://picsum.photos/1200/800?random=3" alt="Image 3" draggable="false">
<div class="drag-indicator">拖拽查看</div>
</div>
<div class="main-slide">
<img src="https://picsum.photos/1200/800?random=4" alt="Image 4" draggable="false">
<div class="drag-indicator">拖拽查看</div>
</div>
<div class="main-slide">
<img src="https://picsum.photos/1200/800?random=5" alt="Image 5" draggable="false">
<div class="drag-indicator">拖拽查看</div>
</div>
<div class="main-slide">
<img src="https://picsum.photos/1200/800?random=6" alt="Image 6" draggable="false">
<div class="drag-indicator">拖拽查看</div>
</div>
</div>
<div class="drag-info">您可以拖拽主图片查看完整内容</div>
<div class="thumbnails-container">
<div class="thumbnails">
<div class="thumbnail active" data-index="0">
<img src="https://picsum.photos/120/80?random=1" alt="Thumbnail 1">
</div>
<div class="thumbnail" data-index="1">
<img src="https://picsum.photos/120/80?random=2" alt="Thumbnail 2">
</div>
<div class="thumbnail" data-index="2">
<img src="https://picsum.photos/120/80?random=3" alt="Thumbnail 3">
</div>
<div class="thumbnail" data-index="3">
<img src="https://picsum.photos/120/80?random=4" alt="Thumbnail 4">
</div>
<div class="thumbnail" data-index="4">
<img src="https://picsum.photos/120/80?random=5" alt="Thumbnail 5">
</div>
<div class="thumbnail" data-index="5">
<img src="https://picsum.photos/120/80?random=6" alt="Thumbnail 6">
</div>
</div>
</div>
<div class="navigation">
<button class="nav-btn prev-btn" disabled>上一张</button>
<button class="nav-btn next-btn">下一张</button>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const mainSlides = document.querySelectorAll('.main-slide');
const thumbnails = document.querySelectorAll('.thumbnail');
const prevBtn = document.querySelector('.prev-btn');
const nextBtn = document.querySelector('.next-btn');
const thumbnailsContainer = document.querySelector('.thumbnails-container');
const dragIndicators = document.querySelectorAll('.drag-indicator');
let currentIndex = 0;
let isDragging = false;
let startPosX = 0;
let currentTranslate = 0;
let prevTranslate = 0;
let animationID;
// 初始化相册
function initGallery() {
updateButtons();
setupThumbnailScroll();
setupDragEvents();
}
// 更新导航按钮状态
function updateButtons() {
prevBtn.disabled = currentIndex === 0;
nextBtn.disabled = currentIndex === mainSlides.length - 1;
}
// 设置缩略图滚动位置
function setupThumbnailScroll() {
const activeThumb = thumbnails[currentIndex];
const containerWidth = thumbnailsContainer.offsetWidth;
const thumbWidth = activeThumb.offsetWidth;
const thumbLeft = activeThumb.offsetLeft;
// 计算滚动位置,使当前缩略图居中
const scrollTo = thumbLeft - (containerWidth / 2) + (thumbWidth / 2);
thumbnailsContainer.scrollTo({
left: scrollTo,
behavior: 'smooth'
});
}
// 设置拖拽事件
function setupDragEvents() {
mainSlides.forEach((slide, index) => {
const image = slide.querySelector('img');
// 触摸事件
image.addEventListener('touchstart', touchStart(index));
image.addEventListener('touchend', touchEnd);
image.addEventListener('touchmove', touchMove);
// 鼠标事件
image.addEventListener('mousedown', dragStart(index));
image.addEventListener('mouseup', dragEnd);
image.addEventListener('mouseleave', dragEnd);
image.addEventListener('mousemove', dragMove);
// 防止拖动时选中文本
image.addEventListener('selectstart', (e) => e.preventDefault());
});
}
// 切换到指定索引的幻灯片
function goToSlide(index) {
if (index < 0 || index >= mainSlides.length) return;
mainSlides[currentIndex].classList.remove('active');
thumbnails[currentIndex].classList.remove('active');
currentIndex = index;
mainSlides[currentIndex].classList.add('active');
thumbnails[currentIndex].classList.add('active');
updateButtons();
setupThumbnailScroll();
}
// 上一张
function prevSlide() {
goToSlide(currentIndex - 1);
}
// 下一张
function nextSlide() {
goToSlide(currentIndex + 1);
}
// 触摸开始
function touchStart(index) {
return function(event) {
startPosX = event.touches[0].clientX;
currentTranslate = 0;
prevTranslate = 0;
isDragging = true;
animationID = requestAnimationFrame(animation);
showDragIndicator(index);
};
}
// 触摸移动
function touchMove(event) {
if (!isDragging) return;
const currentPosition = event.touches[0].clientX;
currentTranslate = currentPosition - startPosX;
}
// 触摸结束
function touchEnd() {
if (!isDragging) return;
isDragging = false;
cancelAnimationFrame(animationID);
hideDragIndicator();
// 根据拖动距离决定是否切换幻灯片
if (Math.abs(currentTranslate) > 50) {
if (currentTranslate > 0) {
prevSlide();
} else {
nextSlide();
}
}
}
// 拖拽开始
function dragStart(index) {
return function(event) {
startPosX = event.clientX;
currentTranslate = 0;
prevTranslate = 0;
isDragging = true;
animationID = requestAnimationFrame(animation);
showDragIndicator(index);
};
}
// 拖拽移动
function dragMove(event) {
if (!isDragging) return;
const currentPosition = event.clientX;
currentTranslate = currentPosition - startPosX;
}
// 拖拽结束
function dragEnd() {
if (!isDragging) return;
isDragging = false;
cancelAnimationFrame(animationID);
hideDragIndicator();
// 根据拖动距离决定是否切换幻灯片
if (Math.abs(currentTranslate) > 50) {
if (currentTranslate > 0) {
prevSlide();
} else {
nextSlide();
}
}
}
// 动画帧
function animation() {
if (!isDragging) return;
const activeSlide = mainSlides[currentIndex];
const image = activeSlide.querySelector('img');
// 应用平移效果
image.style.transform = `translateX(${currentTranslate}px)`;
animationID = requestAnimationFrame(animation);
}
// 显示拖拽指示器
function showDragIndicator(index) {
dragIndicators[index].style.display = 'block';
}
// 隐藏拖拽指示器
function hideDragIndicator() {
dragIndicators.forEach(indicator => {
indicator.style.display = 'none';
});
// 重置图片位置
mainSlides.forEach(slide => {
const image = slide.querySelector('img');
image.style.transform = 'translateX(0)';
});
}
// 事件监听
prevBtn.addEventListener('click', prevSlide);
nextBtn.addEventListener('click', nextSlide);
thumbnails.forEach(thumbnail => {
thumbnail.addEventListener('click', function() {
const index = parseInt(this.getAttribute('data-index'));
goToSlide(index);
});
});
// 键盘导航
document.addEventListener('keydown', function(e) {
if (e.key === 'ArrowLeft') {
prevSlide();
} else if (e.key === 'ArrowRight') {
nextSlide();
}
});
// 初始化相册
initGallery();
});
</script>
</body>
</html>