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

小时天气预报分页加载系统JavaScript代码优化求助

小时天气预报分页功能代码优化

核心优化点

  • 提取渲染单小时行的独立函数,消除重复代码块
  • 新增分页状态变量currentPage,统一管理已加载的页码,支持多次点击加载更多
  • 改用事件委托实现行交互逻辑,无需每次新增行后重新绑定所有事件,提升性能
  • 修复原代码中重复调用setValue("temp")的冗余问题
  • 加载完成所有数据后自动隐藏「加载更多」按钮
  • 简化数组拆分函数的实现逻辑

优化后的完整代码

function renderHourlyWeather(hourly) {
  hourlySection.innerHTML = "";
  const chunkSize = 12;
  const smallArrays = splitHours(hourly, chunkSize);
  let currentPage = 0; // 分页状态,记录已加载的页码

  // 初始化加载第一页
  renderHourPage(smallArrays[currentPage]);
  updateLoadMoreButton();

  // 加载更多按钮绑定事件
  const loadMoreBtn = document.querySelector(".load-more");
  loadMoreBtn.addEventListener("click", () => {
    currentPage++;
    renderHourPage(smallArrays[currentPage]);
    updateLoadMoreButton();
  });

  // 渲染单页小时数据
  function renderHourPage(hourDataArray) {
    hourDataArray.forEach(hour => {
      const hourRowElement = hourRowTemplate.content.cloneNode(true);
      
      // 基础时间与图标设置
      setValue("day", DAY_FORMATTER.format(hour.timestamp), { parent: hourRowElement });
      setValue("time", HOUR_FORMATTER.format(hour.timestamp), { parent: hourRowElement });
      hourRowElement.querySelector("[data-icon]").src = getIconUrl(hour.iconCode);

      // 温度区域逻辑(修复重复设置temp的问题)
      const tempButton = hourRowElement.querySelector("button");
      const tempOnly = hourRowElement.querySelector(".temp-only");
      if (hour.chanceOfPrecip > 0) {
        setValue("temp", hour.temp, { parent: hourRowElement });
        tempButton.classList.remove("hidden");
      } else {
        setValue("temp-no-precip", hour.temp, { parent: hourRowElement });
        tempOnly.classList.remove("hidden");
      }

      // 其他气象数据设置
      setValue("precip-percent", hour.chanceOfPrecip, { parent: hourRowElement });
      setValue("fl-temp", hour.feelsLike, { parent: hourRowElement });
      setValue("wind", hour.windSpeed, { parent: hourRowElement });
      setValue("precip-amount", hour.precipAmount, { parent: hourRowElement });
      setValue("humidity", hour.humidity, { parent: hourRowElement });
      setValue("dew-point", hour.dewPoint, { parent: hourRowElement });

      hourlySection.append(hourRowElement);
    });
    // 新增行后初始化样式
    initRowStyles();
  }

  // 更新加载更多按钮状态
  function updateLoadMoreButton() {
    const loadMoreBtn = document.querySelector(".load-more");
    if (currentPage >= smallArrays.length - 1) {
      loadMoreBtn.classList.add("hidden");
    } else {
      loadMoreBtn.classList.remove("hidden");
    }
  }

  // 事件委托实现行交互逻辑(替代原tableRowInteractive)
  const table = document.querySelector('.hour-section');
  table.addEventListener("click", (e) => {
    const row = e.target.closest('tr');
    if (!row) return;

    // 处理温度降水组点击
    if (e.target.closest('.temp-percent')) {
      const group = row.querySelectorAll('.temp-percent');
      toggleGroup(group[0], group[1]);
    }

    // 处理湿度露点组点击
    if (e.target.closest('.dew-humidity-group-tr')) {
      const group2 = row.querySelectorAll('.dew-humidity-group-tr');
      toggleGroup(group2[0], group2[1]);
    }
  });

  // 初始化行样式(降水概率、露点等级)
  function initRowStyles() {
    const rows = document.querySelectorAll('.hour-section tr');
    rows.forEach(row => {
      // 设置降水概率样式
      const percentage = parseInt(row.querySelector("[data-precip-percent]").textContent);
      const tempPercentElements = row.querySelectorAll('.temp-percent');
      tempPercentElements.forEach(el => {
        if (percentage > 80) el.classList.add("high");
        else if (percentage > 50) el.classList.add("medium");
        else if (percentage >= 20) el.classList.add("low");
      });

      // 设置露点等级样式
      const dewPointNumber = parseInt(row.querySelector('[data-dew-point]').textContent);
      const labels = row.querySelectorAll('.dew-humidity-group-tr .label');
      labels.forEach(label => {
        if (dewPointNumber >= 70) label.classList.add("bad");
        else if (dewPointNumber > 60) label.classList.add("normal");
        else if (dewPointNumber > 50) label.classList.add("good");
        else label.classList.add("best");
      });
    });
  }

  // 拆分数组为指定大小的块
  function splitHours(hourArray, chunkSize) {
    return Array.from({ length: Math.ceil(hourArray.length / chunkSize) }, (_, i) => 
      hourArray.slice(i * chunkSize, (i + 1) * chunkSize)
    );
  }
}

优化说明

  1. 代码复用:将重复的小时行渲染逻辑封装为renderHourPage函数,避免原代码中两次几乎完全相同的循环块。
  2. 分页管理:通过currentPage变量跟踪已加载页码,支持多次点击加载更多,直到所有数据加载完成。
  3. 事件委托:将点击事件绑定到父容器table上,无需每次新增行后重新遍历绑定事件,减少DOM操作次数,提升性能。
  4. 逻辑修复:移除原代码中重复的setValue("temp")调用,避免不必要的DOM操作。
  5. 按钮状态控制:所有数据加载完成后自动隐藏「加载更多」按钮,优化用户体验。
  6. 代码简化:使用Array.from简化数组拆分函数splitHours的实现,逻辑更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:25:08