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

基于JS与localStorage的投票系统:替换最少得票设计的实现求助

问题描述

我开发了一个基于JavaScript和localStorage的投票系统,用来存储设计方案及对应票数。现在想实现将得票最少的设计替换为新设计的功能,但目前只能把克隆的新设计添加到DOM开头,导致票数顺序混乱,而且图库设计数量会超过6个。另外,不确定多个设计票数相同时的处理逻辑,求技术帮助。

解决方案

1. 核心重构:优化数据结构

当前用单独变量存储每个票数,扩展性极差。改成数组+对象的结构,把每个设计的信息(票数、样式类、唯一ID)统一管理:

  • 用数组存储所有设计的投票数据,每个元素是包含id、votes、elementClass的对象
  • localStorage中用单个键存储整个数组的JSON字符串,替代多个独立的voteValX键

2. 实现替换逻辑与同票处理

替换流程

  1. 找出当前票数最低的所有设计
  2. 从候选中选择一个(默认随机选,公平性更好;也可改成选最先出现/最旧的设计)
  3. 用新设计的样式替换该位置的设计,重置票数为0
  4. 更新localStorage并同步DOM

同票处理策略(三选一)

  • 随机选择:从所有最低票设计中随机挑一个替换(代码默认采用)
  • 优先替换最先出现的:选数组中第一个最低票的设计
  • 优先替换最旧的:给每个设计添加createTime字段,替换时间最早的

完整优化代码

// 初始化投票数据
function initVotingData() {
  let votingData = localStorage.getItem('votingData');
  if (!votingData) {
    // 初始6个设计,票数默认0
    votingData = JSON.stringify([
      { id: 1, votes: 0, elementClass: 'red' },
      { id: 2, votes: 0, elementClass: 'blue' },
      { id: 3, votes: 0, elementClass: 'purple' },
      { id: 4, votes: 0, elementClass: 'red' },
      { id: 5, votes: 0, elementClass: 'blue' },
      { id: 6, votes: 0, elementClass: 'purple' }
    ]);
    localStorage.setItem('votingData', votingData);
  }
  return JSON.parse(votingData);
}

let votingData = initVotingData();
const container = $('.container');

// 渲染设计与票数
function renderDesigns() {
  container.empty();
  votingData.forEach((item) => {
    const designEl = $(`<div class="${item.elementClass} circle">
                          <span class="voteVal">${item.votes}</span>
                          <button class="voteBtn" data-id="${item.id}">投票</button>
                        </div>`);
    container.append(designEl);
  });
  bindVoteEvents();
}

// 绑定投票点击事件
function bindVoteEvents() {
  $('.voteBtn').on('click', function() {
    const id = Number($(this).data('id'));
    const designItem = votingData.find(item => item.id === id);
    if (designItem) {
      designItem.votes++;
      $(this).siblings('.voteVal').text(designItem.votes);
      localStorage.setItem('votingData', JSON.stringify(votingData));
    }
  });
}

// 重置所有票数
$('.resetAllVotes').on('click', function() {
  votingData.forEach(item => item.votes = 0);
  localStorage.setItem('votingData', JSON.stringify(votingData));
  renderDesigns();
});

// 主设计颜色切换
$('.btnred').on('click', () => {
  $("#main").removeClass().addClass("red");
  localStorage.setItem('mainDesignClass', 'red');
});
$(".btnblue").on("click", () => {
  $("#main").removeClass().addClass("blue");
  localStorage.setItem('mainDesignClass', 'blue');
});
$(".btnpurple").on("click", () => {
  $("#main").removeClass().addClass("purple");
  localStorage.setItem('mainDesignClass', 'purple');
});

// 替换最低票设计
$(".clone").on("click", function () {
  // 1. 找出所有最低票设计
  const minVotes = Math.min(...votingData.map(item => item.votes));
  const lowestVoteDesigns = votingData.filter(item => item.votes === minVotes);
  
  // 2. 随机选择一个要替换的设计
  const randomTargetIdx = Math.floor(Math.random() * lowestVoteDesigns.length);
  const targetDesign = lowestVoteDesigns[randomTargetIdx];
  const dataIndex = votingData.findIndex(item => item.id === targetDesign.id);

  // 3. 获取新设计的样式类
  const newClass = localStorage.getItem('mainDesignClass') || 'red';
  
  // 4. 更新数据:替换目标设计,重置票数为0
  votingData[dataIndex] = {
    id: Date.now(), // 时间戳做唯一ID
    votes: 0,
    elementClass: newClass
  };
  
  // 5. 同步存储与DOM
  localStorage.setItem('votingData', JSON.stringify(votingData));
  renderDesigns();
});

// 页面初始化
$(document).ready(function() {
  const mainClass = localStorage.getItem('mainDesignClass') || 'red';
  $('#main').addClass(mainClass);
  renderDesigns();
});

优化亮点

  • 数据统一管理:避免大量重复变量,后续调整设计数量只需修改初始数组
  • DOM自动同步:数据变化后重新渲染,彻底解决顺序混乱问题
  • 灵活扩展:同票处理策略可按需切换,新增功能只需修改对应模块
  • 存储高效:单个localStorage键存储所有数据,减少IO操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 10:50:16