mcpField
Q
quick-view-modal

quick-view-modal

github.com/finsilabs设计与 UI6076 次安装6 天前更新
代码仓库

关于 quick-view-modal

指导在商品列表页实现商品快速预览,让顾客查看图片、规格、描述和价格并直接加入购物车。内容涵盖 Shopify、WooCommerce、BigCommerce 及自定义无头 storefront 的实现方式。

主要功能

  1. 01在列表页弹窗预览商品
  2. 02展示图片、规格、描述和价格
  3. 03支持选择规格并加入购物车
  4. 04介绍多种电商平台的实现方式
  5. 05提供无头 storefront 的弹窗实现指导

适用场景

  1. 01减少顾客在列表与详情页间跳转
  2. 02为简单规格商品提供快速选购
  3. 03在搜索结果中添加快速加入购物车
  4. 04为内容较重的商品详情页提供轻量预览

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill quick-view-modal

安装后在 Claude Code 中输入/quick-view-modal确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

tile.json
evals/native-dialog-modal-with-focus-managemen/
criteria.json
task.md
evals/quick-view-trigger-button-on-product-car/
criteria.json
task.md
evals/variant-selection-cart-integration-and-l/
criteria.json
task.md

详细介绍

快速查看弹窗

概述

实现一个商品快速查看覆盖层,让购物者无需离开商品列表页,就能预览商品的关键信息——图片、款式、描述、价格,并将商品加入购物车。快速查看可降低购物者浏览多个商品时的操作阻力,最适用于款式结构简单(1–2 个款式维度)的商品。

何时使用此技能

  • 转化数据表明购物者经常离开 PLP,但从 PDP 跳出
  • 商品的款式结构简单(1–2 个款式维度),适合快速选择
  • 在系列页或搜索结果的商品卡片上实现“快速添加”按钮
  • 网站的 PDP 内容较多(图片很多、包含评论区),精简预览可以减少操作阻力

核心说明

第 1 步:确定商家的平台并选择合适的方案
平台推荐方案原因
Shopify在主题中启用快速查看(Dawn、Sense、Craft 均包含此功能),或安装 Quick View – Instant Preview 应用Dawn 内置的“快速添加”按钮可直接从系列页将商品加入购物车;Quick View 应用则提供完整的商品预览和款式选择
WooCommerce安装 YITH WooCommerce Quick View(免费)或 WooCommerce Quick View ProYITH Quick View 是使用最广泛的选项——会在悬停时显示“快速查看”按钮,点击后打开包含图库、款式和“加入购物车”功能的弹窗,且无需自定义代码
BigCommerce在 Storefront → My Themes → Customize → Product Cards 中启用 Quick View(Cornerstone 主题)Cornerstone 内置快速查看弹窗,可在主题编辑器中启用,无需编写代码
Custom / Headless使用原生 <dialog> 元素构建弹窗,并实现商品延迟获取、款式选择和焦点管理<dialog> 内置焦点锁定和按 Escape 关闭功能;延迟获取可降低初始页面体积
第 2 步:启用并配置快速查看

Shopify

内置快速添加(Dawn、Sense、Craft):

Dawn 的系列页默认包含“快速添加”按钮,可直接将商品加入购物车,无需打开弹窗。启用或配置方法:

  1. 前往 Online Store → Themes → Customize
  2. 导航至系列页模板
  3. 在 Product card 区域中,启用 Quick add button
  4. 设置按钮样式:Standard(显示“Quick Add”)或 Icon(加号图标)

注意:Dawn 的快速添加仅适用于没有款式或只有一个款式维度的商品。对于包含多个选项类型(颜色 + 尺码)的商品,它会改为打开商品页。

完整的快速查看弹窗(Quick View – Instant Preview 应用):

  1. 从 Shopify App Store 安装(提供免费套餐)
  2. 此应用会在所有系列页的商品卡片悬停时添加“快速查看”按钮
  3. 在应用设置中配置弹窗中显示的商品区域:图片、描述、评论、尺码指南
  4. 购物者可以选择所有款式选项并将商品加入购物车,而无需离开系列页
  5. 无需编辑主题代码——应用通过 App Block 注入

WooCommerce

YITH WooCommerce Quick View(免费):

  1. 从 WordPress.org 安装并启用
  2. 前往 YITH → Quick View → General Settings
  3. 设置 Trigger:选择“悬停时显示快速查看按钮”(推荐)或点击商品图片
  4. 配置 Modal content:选择要显示的区域——图库、价格、简短描述、款式(加入购物车)、评论摘要
  5. 设置 Modal width,并选择是否在弹窗中显示“查看完整商品”链接(推荐)
  6. 在 Style 中调整按钮文本、颜色和位置,使其与主题一致

此插件会自动为商店页、存档页和搜索结果页中的 .product 元素添加“快速查看”按钮。


BigCommerce

内置快速查看(Cornerstone 主题):

  1. 前往 店面 → 我的主题 → 自定义
  2. 找到 商品卡片 部分(具体位置取决于主题版本,可能在全局设置或分类页面设置中)
  3. 将 启用快速查看 切换为开启
  4. 配置要显示的元素:图片库、选项/变体、添加到购物车按钮、价格
  5. BigCommerce 的快速查看会加载商品的全部变体选项和图片

对于非 Cornerstone 主题,请查看主题文档,快速查看功能的支持情况因主题而异。如果主题未包含此功能,请从 BigCommerce App Marketplace 安装 Quick View 应用。


自定义/无头架构

商品卡片上的快速查看按钮:

// ProductCard.jsx
export function ProductCard({ product, onQuickView }) {
  return (
    <article className="product-card">
      <div className="product-card__image-wrapper">
        <a href={product.url}>
          <img src={product.image} alt={product.name} loading="lazy" />
        </a>
        <button className="quick-view-btn"
          onClick={() => onQuickView(product.id)}
          aria-label={`Quick view ${product.name}`}>
          Quick View
        </button>
      </div>
      <a href={product.url} className="product-card__name">{product.name}</a>
      <p className="product-card__price">${product.price}</p>
    </article>
  );
}
/* Always visible on touch; appears on hover for mouse users */
.quick-view-btn { position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%);
  opacity: 0; transition: opacity 0.15s; }
.product-card:hover .quick-view-btn, .product-card:focus-within .quick-view-btn { opacity: 1; }
@media (hover: none) { .quick-view-btn { opacity: 1; } }

使用原生 <dialog> 的模态框(内置焦点约束和按 Escape 键关闭):

// QuickViewModal.jsx
import { useEffect, useRef } from 'react';

export function QuickViewModal({ isOpen, product, loading, onClose, onAddToCart }) {
  const dialogRef = useRef(null);

  useEffect(() => {
    const dialog = dialogRef.current;
    if (!dialog) return;
    if (isOpen) dialog.showModal();
    else dialog.close();
  }, [isOpen]);

  return (
    <dialog ref={dialogRef} className="quick-view-dialog"
      onClose={onClose}
      onClick={(e) => { if (e.target === dialogRef.current) onClose(); }}
      aria-label={product ? `Quick view: ${product.name}` : 'Quick view'}>
      <button className="close-btn" onClick={onClose} aria-label="Close quick view">&times;</button>

      {loading && (
        <div aria-live="polite" aria-label="Loading product details">
          {/* Skeleton loaders */}
          <div className="skeleton skeleton--image" />
          <div className="skeleton skeleton--title" />
        </div>
      )}

      {!loading && product && (
        <QuickViewBody product={product} onAddToCart={onAddToCart} onClose={onClose} />
      )}
    </dialog>
  );
}

带变体选择的快速查看内容:

function QuickViewBody({ product, onAddToCart, onClose }) {
  const [selectedVariant, setSelectedVariant] = useState(product.variants[0] ?? null);

  return (
    <div className="quick-view-body">
      <img src={selectedVariant?.image ?? product.images[0]} alt={product.name} />
      <div className="quick-view-details">
        <h2>{product.name}</h2>
        <p>${selectedVariant?.price ?? product.price}</p>

        {product.options.map(option => (
          <fieldset key={option.name}>
            <legend>{option.name}</legend>
            {option.values.map(value => {
              const variant = product.variants.find(v => v.options[option.name] === value);
              return (
                <label key={value}>
                  <input type="radio" name={option.name} value={value}
                    checked={selectedVariant?.options[option.name] === value}
                    disabled={!variant || variant.inventory === 0}
                    onChange={() => setSelectedVariant(variant)} />
                  {value}{variant?.inventory === 0 ? ' (sold out)' : ''}
                </label>
              );
            })}
          </fieldset>
        ))}

        <button className="btn-primary"
          disabled={!selectedVariant || selectedVariant.inventory === 0}
          onClick={() => onAddToCart({ variantId: selectedVariant.id, quantity: 1 }).then(onClose)}>
          Add to Cart
        </button>
        <a href={product.url}>View Full Details</a>
      </div>
    </div>
  );
}

模态框关闭时,将焦点返回触发按钮:

const triggerRef = useRef(null);

function handleOpenQuickView(productId, triggerElement) {
  triggerRef.current = triggerElement; // store the button that was clicked
  openQuickView(productId);
}

function handleCloseQuickView() {
  closeQuickView();
  requestAnimationFrame(() => triggerRef.current?.focus());
}

最佳实践

  • 始终提供“查看完整详情”链接——快速查看是快捷方式,而非替代品;复杂商品(图片较多、有评论)需要查看完整的商品详情页
  • 打开时再延迟获取商品数据——不要将完整商品数据嵌入卡片 HTML 中;按需获取,以减轻页面负担
  • 显示加载骨架屏——获取数据需要 100–300 ms;骨架屏可避免用户感知到布局偏移
  • 点击背景时关闭——点击模态框内容区域以外的位置应关闭模态框
  • 打开时禁止页面主体滚动——在移动设备上,为对话框设置 overscroll-behavior: contain,可防止底层页面滚动
  • 仅对简单商品使用快速查看——有 3 个以上变体维度、尺码指南或详细规格表的商品应跳转到完整商品详情页

常见问题

问题解决方案
模态框关闭后焦点丢失打开前保存触发元素的引用;关闭后在 requestAnimationFrame 中调用 .focus()
触屏设备上看不到快速查看按钮使用 @media (hover: none),确保在触屏屏幕上始终显示按钮;不要只依赖悬停
模态框打开时页面主体仍可滚动模态框打开时,为 body 设置 overflow: hidden;关闭时恢复
图片更改后变体选择被重置将 selectedVariant 按变体 ID 而非数组中的位置保存在状态中
需要完整商品详情页的商品却打开了快速查看检测有 3 个以上选项或需要尺码指南的商品,并直接跳转到商品详情页

相关技能

  • @product-page-design
  • @accessibility-commerce
  • @responsive-storefront
  • @faceted-navigation

评论

支持 Markdown