商城自定义评论模块轮播,适配不同的设备

这种样式在网站非常美观,而且用户可以直接点击下面的产品访问产品。

9edfb1
Avatar
Emma Watson
★★★★★
这款产品的设计感真的太棒了,完全符合我的审美。
Product
高端无线耳机 Pro查看详情 >
Avatar
Liam Chen
★★★★★
第二次回购了,排版整洁,购物体验极佳!我会推荐给我的所有朋友们。
Product
极简风手机壳查看详情 >
Avatar
Sophia Li
★★★★☆
包装很用心,颜色正,推荐购买。
Product
产品名称 3查看详情 >
Avatar
User 4
★★★★★
做工精细,实物比照片还要好看。每一个细节都处理得非常完美。
Product
产品名称 4查看详情 >
Avatar
User 5
★★★★★
客服态度很好,解答非常有耐心。物流也非常快。
Product
产品名称 5查看详情 >
Avatar
User 6
★★★★★
物流速度惊人,隔天就收到了!产品质量完全超出预期。
Product
产品名称 6查看详情 >
Avatar
User 7
★★★★★
已经分享给身边的朋友了。好东西值得被更多人发现。
Product
产品名称 7查看详情 >
Avatar
User 8
★★★★★
非常精致,这个价格能买到这种品质很划算。
Product
产品名称 8查看详情 >
Avatar
User 9
★★★★★
好评好评好评,重要的事说三遍。
Product
产品名称 9查看详情 >
Avatar
User 10
★★★★★
期待后续更多新款产品。这家的风格我太喜欢了。
Product
产品名称 10查看详情 >
Avatar
User 11
★★★★★
手感不错,没有异味,材质用得很扎实。
Product
产品名称 11查看详情 >
Avatar
User 12
★★★★★
已经是这家的忠实粉丝了。每次上新都会来看看。
Product
产品名称 12查看详情 >
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        /* 容器基础样式 */
        .custom-review-container {
            max-width: 1200px;
            margin: 20px auto;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            position: relative;
            overflow: hidden;
            padding: 20px 0;
            user-select: none;
        }

        /* 轨道:使用 align-items: stretch 确保所有子卡片高度一致 */
        .review-track {
            display: flex;
            align-items: stretch; 
            transition: transform 0.5s cubic-bezier(0.2, 0, 0.2, 1);
            gap: 15px;
            will-change: transform;
        }

        /* 评价卡片样式 */
        .review-card {
            flex-shrink: 0;
            background: #ffffff;
            border: 1px solid #ebebeb;
            border-radius: 12px;
            padding: 18px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.05);
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            box-sizing: border-box;
            transition: transform 0.3s;
            /* 确保即使没内容也有基础高度 */
            min-height: 250px; 
        }

        .review-card:hover {
            transform: translateY(-5px);
        }

        /* 用户及文字信息 */
        .reviewer-info { display: flex; align-items: center; margin-bottom: 12px; }
        .avatar-img { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; margin-right: 12px; background: #eee; }
        .reviewer-name { font-size: 14px; font-weight: 600; color: #333; }
        .stars { color: #FFBC00; font-size: 14px; margin-bottom: 10px; }
        
        /* 文本区域:flex-grow 配合 align-items: stretch 实现等高 */
        .review-text {
            font-size: 13px; color: #555; line-height: 1.6; margin-bottom: 15px;
            display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
            overflow: hidden; flex-grow: 1;
        }

        /* 产品链接区 */
        .product-link {
            text-decoration: none; display: flex; align-items: center;
            border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: auto;
        }
        .product-img { width: 45px; height: 45px; border-radius: 6px; margin-right: 10px; object-fit: cover; }
        .product-info { flex: 1; overflow: hidden; }
        .product-name { font-size: 11px; color: #222; font-weight: 500; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .view-detail { font-size: 10px; color: #0073aa; margin-top: 2px; }

        /* 控制按钮 */
        .nav-btn {
            position: absolute; top: 50%; transform: translateY(-50%);
            background: white; border: 1px solid #eee; width: 40px; height: 40px;
            border-radius: 50%; cursor: pointer; z-index: 10;
            display: flex; align-items: center; justify-content: center;
            box-shadow: 0 4px 10px rgba(0,0,0,0.1);
            transition: all 0.2s;
            outline: none;
            font-weight: bold;
        }
        .nav-btn:hover { background: #f9f9f9; color: #0073aa; }
        .nav-btn:active { background: #f0f0f0; transform: translateY(-50%) scale(0.9); }
        .prev-btn { left: 10px; }
        .next-btn { right: 10px; }
    </style>
</head>
<body>

<div class="custom-review-container" id="carouselContainer">
    <button class="nav-btn prev-btn" id="prevBtn" aria-label="Previous">❮</button>
    <div class="review-track" id="reviewTrack">
        <!-- 评价 1-12 组内容 -->
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=1" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">Emma Watson</div>
            </div>
            <div class="stars">★★★★★</div>
            <div class="review-text">这款产品的设计感真的太棒了,完全符合我的审美。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=1" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">高端无线耳机 Pro</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=2" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">Liam Chen</div>
            </div>
            <div class="stars">★★★★★</div>
            <div class="review-text">第二次回购了,排版整洁,购物体验极佳!我会推荐给我的所有朋友们。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=2" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">极简风手机壳</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=3" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">Sophia Li</div>
            </div>
            <div class="stars">★★★★☆</div>
            <div class="review-text">包装很用心,颜色正,推荐购买。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=3" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">产品名称 3</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=4" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">User 4</div>
            </div>
            <div class="stars">★★★★★</div>
            <div class="review-text">做工精细,实物比照片还要好看。每一个细节都处理得非常完美。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=4" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">产品名称 4</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=5" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">User 5</div>
            </div>
            <div class="stars">★★★★★</div>
            <div class="review-text">客服态度很好,解答非常有耐心。物流也非常快。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=5" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">产品名称 5</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=6" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">User 6</div>
            </div>
            <div class="stars">★★★★★</div>
            <div class="review-text">物流速度惊人,隔天就收到了!产品质量完全超出预期。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=6" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">产品名称 6</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=7" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">User 7</div>
            </div>
            <div class="stars">★★★★★</div>
            <div class="review-text">已经分享给身边的朋友了。好东西值得被更多人发现。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=7" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">产品名称 7</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=8" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">User 8</div>
            </div>
            <div class="stars">★★★★★</div>
            <div class="review-text">非常精致,这个价格能买到这种品质很划算。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=8" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">产品名称 8</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=9" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">User 9</div>
            </div>
            <div class="stars">★★★★★</div>
            <div class="review-text">好评好评好评,重要的事说三遍。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=9" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">产品名称 9</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=10" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">User 10</div>
            </div>
            <div class="stars">★★★★★</div>
            <div class="review-text">期待后续更多新款产品。这家的风格我太喜欢了。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=10" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">产品名称 10</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=11" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">User 11</div>
            </div>
            <div class="stars">★★★★★</div>
            <div class="review-text">手感不错,没有异味,材质用得很扎实。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=11" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">产品名称 11</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
        <div class="review-card">
            <div class="reviewer-info">
                <img src="https://i.pravatar.cc/100?u=12" alt="Avatar" class="avatar-img">
                <div class="reviewer-name">User 12</div>
            </div>
            <div class="stars">★★★★★</div>
            <div class="review-text">已经是这家的忠实粉丝了。每次上新都会来看看。</div>
            <a href="#" class="product-link">
                <img src="https://picsum.photos/100/100?random=12" alt="Product" class="product-img">
                <div class="product-info"><span class="product-name">产品名称 12</span><span class="view-detail">查看详情 ></span></div>
            </a>
        </div>
    </div>
    <button class="nav-btn next-btn" id="nextBtn" aria-label="Next">❯</button>
</div>

<script>
    const track = document.getElementById('reviewTrack');
    const container = document.getElementById('carouselContainer');
    const nextBtn = document.getElementById('nextBtn');
    const prevBtn = document.getElementById('prevBtn');
    
    let originalCount = 0;
    let currentIndex = 0;
    let cardWidth = 0;
    let isTransitioning = false;
    let autoPlayTimer = null;
    const gap = 15;

    function setupCarousel() {
        const allCards = Array.from(track.children);
        originalCount = allCards.length;

        // 构建三组用于无缝循环
        const beforeNodes = allCards.map(node => node.cloneNode(true));
        const afterNodes = allCards.map(node => node.cloneNode(true));

        beforeNodes.forEach(node => track.insertBefore(node, track.firstChild));
        afterNodes.forEach(node => track.appendChild(node));

        currentIndex = originalCount; 
        
        // 确保图片加载或布局稳定后计算
        window.addEventListener('load', calculateLayout);
        setTimeout(calculateLayout, 100);
        startAutoPlay();
    }

    function calculateLayout() {
        const containerWidth = container.offsetWidth;
        let visibleCount = 4;
        if (window.innerWidth <= 600) visibleCount = 2;
        else if (window.innerWidth <= 1024) visibleCount = 3;

        cardWidth = (containerWidth - (visibleCount - 1) * gap) / visibleCount;
        
        const allCardsInDom = track.querySelectorAll('.review-card');
        allCardsInDom.forEach(card => {
            card.style.width = `${cardWidth}px`;
        });

        updatePosition(false);
    }

    function updatePosition(animate = true) {
        if (animate) {
            track.style.transition = 'transform 0.5s cubic-bezier(0.2, 0, 0.2, 1)';
        } else {
            track.style.transition = 'none';
        }
        const offset = currentIndex * (cardWidth + gap);
        track.style.transform = `translateX(-${offset}px)`;
    }

    function move(step) {
        if (isTransitioning) return;
        isTransitioning = true;
        currentIndex += step;
        updatePosition(true);
    }

    // 监听过渡结束,处理无缝跳转
    track.addEventListener('transitionend', () => {
        isTransitioning = false;
        
        if (currentIndex >= originalCount * 2) {
            currentIndex = originalCount;
            updatePosition(false);
        } else if (currentIndex <= 0) {
            currentIndex = originalCount;
            updatePosition(false);
        }
    });

    // 强力纠偏逻辑,防止长时间运行后的累计误差
    function startAutoPlay() {
        stopAutoPlay();
        autoPlayTimer = setInterval(() => {
            if (!isTransitioning) move(1);
        }, 3000);
    }

    function stopAutoPlay() {
        if (autoPlayTimer) clearInterval(autoPlayTimer);
    }

    // 点击事件改为直接处理,并确保重置播放器
    nextBtn.addEventListener('click', (e) => {
        e.preventDefault();
        move(1);
        startAutoPlay();
    });

    prevBtn.addEventListener('click', (e) => {
        e.preventDefault();
        move(-1);
        startAutoPlay();
    });

    // 鼠标交互
    container.addEventListener('mouseenter', stopAutoPlay);
    container.addEventListener('mouseleave', startAutoPlay);

    // 初始化
    setupCarousel();
    window.addEventListener('resize', calculateLayout);

    // 触屏支持
    let startX = 0;
    container.addEventListener('touchstart', (e) => {
        startX = e.touches[0].clientX;
        stopAutoPlay();
    }, {passive: true});

    container.addEventListener('touchend', (e) => {
        const delta = startX - e.changedTouches[0].clientX;
        if (Math.abs(delta) > 50) {
            move(delta > 0 ? 1 : -1);
        }
        startAutoPlay();
    }, {passive: true});
</script>

</body>
</html>

© 文章版权归白小菌所有,🫰欢迎转发分享。未经允许请勿抄袭转载。

订阅评论
提醒
guest
0 评论
最新
最旧 最多投票
内联反馈
查看所有评论

AI 小菌
现代响应式侧边栏
快捷菜单