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

如何基于下拉选框选项更新用insertAdjacentHTML创建的HTML内容?

问题

页面加载时通过API拉取数据并生成HTML展示,我做了个下拉选择框用来给API返回的数组排序,现在排序后的数组能拿到正确结果,但新生成的HTML总是追加在旧内容后面,没法更新成排序后的新顺序。

原因分析

核心问题是你没在生成新内容前清空容器里的旧内容——每次调用getTours时,都用container.insertAdjacentHTML('beforeend', html)把新HTML往容器末尾加,旧内容一直留在那,自然就堆在一起了。另外还有几个小问题:

  • switch的default分支里写的out;是无效代码,不会起到保留原数组的作用
  • 每次选新排序都重新发API请求,完全没必要,第一次拿到数据后缓存起来,后续直接用缓存的数据排序就行
  • 事件监听写复杂了,你已经用querySelector拿到了下拉元素,不用再循环绑定

解决方案

1. 先清空旧内容

在遍历数组生成新HTML之前,先把容器的内容清空,最简单的就是用container.innerHTML = ''。

2. 缓存API数据

第一次请求到数据后存在变量里,后续排序直接操作缓存的数据,不用重复请求,速度更快。

3. 修复排序逻辑

把排序和渲染分开,单独写个排序函数,完善价格排序的逻辑(你原来的价格分支只有console.log,没实际排序),同时修复default分支的无效代码。

4. 简化事件绑定

直接给下拉元素绑定change事件就行,不用循环。

修改后的完整代码:

const container = document.querySelector('.container');
const sortSelect = document.querySelector('.sort');

let url = 'https://mocki.io/v1/11356aa2-6371-41d4-9d49-77a5e9e9924f';
let toursData = []; // 缓存API返回的原始数据

// 单独抽离渲染函数,负责把数据转成HTML并插入容器
function renderTours(data) {
  // 第一步:清空旧内容
  container.innerHTML = '';
  
  data.forEach((el,i) => {
    const cities = el.cities;
    const lastCity = cities.slice(-1)
    const dates = el.dates.map(d => d.start);
    let availableSpaces = el.dates.map(d => d.availability);
    const fromPrice = dates.length!==0 ? Math.min(...el.dates.map(item => item.eur)) : 0;
    const month = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEPT", "OCT", "NOV", "DEC"];
    const getDate = function (date) {
      if (date!==undefined) {
        const d = new Date(date)
        const day = d.getDate();
        const name = month[d.getMonth()]
        const year = d.getFullYear()
        const fullDate = `${day} ${name} ${year}`;
        return fullDate;
      } else {
        availableSpaces = ['No', 'No'];
        return 'SOLD OUT!'
      }
    }
    let image = el.images.filter(img => img.is_primary===true);
    image.length>0 && image[0].hasOwnProperty('url') && image[0].url!=='' ? image = image[0].url : image = "https://media.istockphoto.com/id/1357365823/vector/default-image-icon-vector-missing-picture-page-for-website-design-or-mobile-app-no-photo.jpg?s=612x612&w=0&k=20&c=PM_optEhHBTZkuJQLlCjLz-v3zzxp-1mpNQZsdjrbns=";
    const operatorName = el.operator_name;
    const html = `Here is my HTML text`;

    container.insertAdjacentHTML('beforeend', html);
  });
}

// 首次加载获取数据并缓存
function getTours() {
  fetch(url)
  .then(res => res.json())
  .then(data => {
    toursData = data;
    renderTours(toursData); // 渲染默认数据
  });
}

// 根据选择的选项排序数据并重新渲染
function sortTours(option) {
  // 复制原数组,避免修改缓存的原始数据
  let sortedData = [...toursData];
  
  switch(option) {
    case 'durasc':
      sortedData.sort((a,b) => a.length - b.length);
      break;
    case 'durdesc':
      sortedData.sort((a,b) => b.length - a.length);
      break;
    case 'prasc':
      // 按最低价格升序排序,无日期的排最后
      sortedData.sort((a,b) => {
        const priceA = a.dates.length ? Math.min(...a.dates.map(item => item.eur)) : Infinity;
        const priceB = b.dates.length ? Math.min(...b.dates.map(item => item.eur)) : Infinity;
        return priceA - priceB;
      });
      break;
    case 'prdesc':
      // 按最低价格降序排序,无日期的排最后
      sortedData.sort((a,b) => {
        const priceA = a.dates.length ? Math.min(...a.dates.map(item => item.eur)) : -Infinity;
        const priceB = b.dates.length ? Math.min(...b.dates.map(item => item.eur)) : -Infinity;
        return priceB - priceA;
      });
      break;
    default:
      // 默认返回原始数组
      sortedData = toursData;
      break;
  }
  
  // 渲染排序后的数据
  renderTours(sortedData);
}

// 绑定下拉选择事件
sortSelect.addEventListener('change', () => {
  sortTours(sortSelect.value);
});

// 页面初始化
getTours();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 16:12:06