You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

页面刷新时保留prod__viewed类状态的技术问询

解决页面刷新后记住已查看商品元素的问题

你当前的核心问题是对sessionStorage的使用逻辑有误——你尝试直接存储jQuery对象,这显然无法正确保存元素状态。下面我会帮你修正代码,实现刷新页面后记住哪些.prod__item已经添加了.prod__viewed类的需求。

问题分析

你的原sessionStorage代码存在几个关键错误:

  • 选择器错误:$("prod__item")缺少类选择器的点号,应该是$(".prod__item")
  • 存储内容错误:你把jQuery对象直接存入sessionStorage,而sessionStorage只能存储字符串类型的数据
  • 读取逻辑错误:读取时直接把存储内容当作类名添加,完全不符合需求逻辑

修正后的完整代码

JavaScript部分

// 页面加载时恢复已查看的商品状态
$(window).on('load', function() {
  // 从sessionStorage读取已查看的商品ID数组,没有则为空数组
  const viewedItems = JSON.parse(sessionStorage.getItem('prodViewed')) || [];
  viewedItems.forEach(itemId => {
    $(`.prod__item[data-id="${itemId}"]`).addClass('prod__viewed');
  });
  // 初始化计数和进度条
  updateProdCountAndProgress();
});

$(window).on('resize scroll', function() {
  $('.prod__item').each(function() {
    const $item = $(this);
    const itemId = $item.data('id');
    // 如果元素已在视口且未标记为已查看
    if ($item.prodInViewport() && !$item.hasClass('prod__viewed')) {
      $item.addClass('prod__viewed');
      // 更新sessionStorage中的已查看列表
      const viewedItems = JSON.parse(sessionStorage.getItem('prodViewed')) || [];
      if (!viewedItems.includes(itemId)) {
        viewedItems.push(itemId);
        sessionStorage.setItem('prodViewed', JSON.stringify(viewedItems));
      }
    }
  });
  updateProdCountAndProgress();
});

// 封装计数和进度条更新逻辑
function updateProdCountAndProgress() {
  const numItems = $('.prod__item').length;
  const totalNumItems = $('.prod__viewed').length;
  const prodCountCheck = $('.prod__count__container');
  const positionY = $(window).scrollTop();
  const pageHeight = $(window).height();
  const scrollHeight = $('.prod__wrapper').height();
  const scrollPercent = scrollHeight > pageHeight ? (positionY / (scrollHeight - pageHeight)) * 100 : 0;
  const prodCountElement = $('.prod__count__container').outerHeight();
  
  if (prodCountCheck.length === 1) {
    $('.prod__count__content')
      .html('<span>You\'ve seen <strong>' + totalNumItems + '</strong> of <strong>' + numItems + '</strong> prods</span>');
    $('.prod__load__bar').css({
      'top': prodCountElement,
      'width': scrollPercent + "%"
    });
  }
}

$.fn.prodInViewport = function() {
  const elementTop = $(this).offset().top;
  const elementBottom = elementTop + $(this).outerHeight();
  const viewportTop = $(window).scrollTop();
  const viewportBottom = viewportTop + $(window).height();
  return elementBottom > viewportTop && elementTop < viewportBottom;
};

HTML部分(需要给每个商品添加唯一标识)

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<section class="prod__wrapper">
  <div class="prod__container">
    <div class="prod__item" data-id="item-1">
      <div class="prod__item--img">
        <img src="https://images-na.ssl-images-amazon.com/images/I/81Lz-p7eRDL._SL1500_.jpg">
      </div>
      <div class="prod__item--deets">
        <div class="prod__name"> My Hero Academia Two Heroes Blu Ray </div>
        <div class="prod__price"> £14.99 </div>
      </div>
    </div>
    <div class="prod__item" data-id="item-2">
      <div class="prod__item--img">
        <img src="https://images-na.ssl-images-amazon.com/images/I/81Lz-p7eRDL._SL1500_.jpg">
      </div>
      <div class="prod__item--deets">
        <div class="prod__name"> My Hero Academia Two Heroes Blu Ray </div>
        <div class="prod__price"> £14.99 </div>
      </div>
    </div>
    <div class="prod__item" data-id="item-3">
      <div class="prod__item--img">
        <img src="https://images-na.ssl-images-amazon.com/images/I/81Lz-p7eRDL._SL1500_.jpg">
      </div>
      <div class="prod__item--deets">
        <div class="prod__name"> My Hero Academia Two Heroes Blu Ray </div>
        <div class="prod__price"> £14.99 </div>
      </div>
    </div>
  </div>
</section>

CSS部分保持你原来的代码不变即可。

关键逻辑说明

  1. 唯一标识:给每个.prod__item添加data-id属性,作为元素的唯一识别符,确保刷新后能准确找到对应的元素。
  2. sessionStorage存储:用JSON数组存储已查看商品的ID,因为sessionStorage只能存字符串,所以用JSON.stringify和JSON.parse进行格式转换。
  3. 页面加载恢复状态:页面加载时读取sessionStorage中的数组,遍历给对应ID的元素添加.prod__viewed类。
  4. 视口检测更新:当元素进入视口且未被标记时,添加类并更新sessionStorage中的数组。
  5. 逻辑封装:把计数和进度条更新逻辑封装成函数,避免重复代码,提高可维护性。

这样修改后,页面刷新后就能正确记住哪些商品已经被标记为已查看了。

内容的提问来源于stack exchange,提问作者Nick Else

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:51:47