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

如何使用Fetch API获取数据并在HTML页面中渲染展示

问题核心原因

当前代码仅完成了「接口请求、控制台打印返回结果」两个环节,完全缺失了DOM渲染逻辑,同时HTML结构没有预留作品信息的展示位置,这就是控制台能看到接口返回数据、页面却没有对应内容的根本原因。

现有代码的具体问题
  • 艺术品ID获取逻辑容错率极低:靠document.getElementsByTagName('img')[art_index].attributes[2].value按属性顺序读取ID,只要后续给img标签新增任意属性(比如class、自定义属性),就会读错值导致接口请求失败。
  • HTML结构缺失信息容器:所有<figure>标签内只有图片标签,没有预留放置作品标题、作者、年代信息的DOM节点,数据没有插入的位置。
  • 接口请求逻辑有隐患:构造请求URL时随意折行,会导致URL拼接多余空格,直接触发接口404错误。
  • 声明了showArtInfo状态变量、stopShow切换方法,但完全没有实现对应逻辑,无法实现「点击展开/再次点击收起、切换作品时自动关闭上一个展开项」的交互。
  • JS文件放在<head>中加载时,页面DOM还未渲染完成,后续加DOM操作逻辑时很容易出现找不到元素的报错。
分步修复方案

第一步:调整HTML结构

  1. 把head里引入main.js的script标签移到body末尾,和bootstrap、popper的script标签放在一起,避免DOM未加载完成就执行JS。
  2. 给每个作品图片加data-art-id自定义属性存作品ID(就是你之前写在img alt里的数字编号),同时在每个figure标签内新增信息展示容器,默认用Bootstrap的d-none类隐藏,示例结构如下:
<figure class="gallery__item gallery__item--1" id="blackmirror" onclick="event.stopPropagation(); getArt(this.id, event)">
    <img class="gallery__img shadow-lg" src="images/black-mirror.jpeg" alt="黑镜" data-art-id="126414">
    <!-- 新增作品信息容器 -->
    <div class="art-info card p-3 mt-2 d-none"></div>
</figure>

6个作品的figure都按这个结构修改,替换对应data-art-id的值即可。

第二步:补全JS逻辑

修改clickedEvent函数,替换成如下可运行的代码,核心补全了ID读取、DOM插入、显示状态切换、错误处理的逻辑:

// 记录当前处于展开状态的作品信息容器
let showArtInfo = null;

async function clickedEvent(art_index, info_index) {
    // 稳妥获取目标图片、对应作品ID、信息容器
    const targetImg = document.getElementsByTagName('img')[art_index];
    const artId = targetImg.dataset.artId;
    const infoContainer = targetImg.closest('.gallery__item').querySelector('.art-info');

    // 点击已展开的作品时,直接收起
    if (showArtInfo === infoContainer) {
        infoContainer.classList.add('d-none');
        showArtInfo = null;
        return;
    }

    // 切换作品前先收起之前展开的信息
    if (showArtInfo) {
        showArtInfo.classList.add('d-none');
    }

    try {
        const headers = new Headers([
            ['Content-Type', 'application/json'],
            ['Accept', 'application/json']
        ]);
        // 注意接口URL不要折行,避免拼接多余空格
        const request = new Request(`https://api.artic.edu/api/v1/artworks/${artId}?fields=id,title,artist_display,date_display,main_reference_number`, {
            method: 'GET',
            headers: headers
        });
        const result = await fetch(request);
        const response = await result.json();
        const artData = response.data;
        console.log(artData);

        // 拼接作品信息插入容器
        infoContainer.innerHTML = `
            <h5 class="card-title">${artData.title}</h5>
            <p class="card-text mb-1"><strong>创作者:</strong>${artData.artist_display}</p>
            <p class="card-text mb-1"><strong>创作时间:</strong>${artData.date_display}</p>
            <p class="card-text text-muted small mb-0">馆藏编号:${artData.main_reference_number}</p>
        `;
        // 显示信息容器
        infoContainer.classList.remove('d-none');
        showArtInfo = infoContainer;
    } catch (err) {
        console.error('作品信息加载失败', err);
        infoContainer.innerHTML = '<p class="text-danger mb-0">信息加载失败,请稍后重试</p>';
        infoContainer.classList.remove('d-none');
    }
}

function getArt(id, event){
    switch(id){
        case 'blackmirror' : {
            event.stopPropagation();
            clickedEvent(0,0)
            break;
        }
        case 'manymansions' : {
            event.stopPropagation();
            clickedEvent(1,0)
            break;
        }
        case 'nightlife' : {
            event.stopPropagation();
            clickedEvent(2,0)
            break;
        }
        case 'room' : {
            event.stopPropagation();
            clickedEvent(3,0)
            break;
        }
        case 'opo' : {
            event.stopPropagation();
            clickedEvent(4,0)
            break;
        } 
        case 'weaving' : {
            event.stopPropagation();
            clickedEvent(5,0)
            break;
        }
    }
}

可选优化(功能跑通后再调整)

  • 当前getArt函数靠硬编码索引匹配作品,写法冗余,可以通过事件对象直接拿到点击的figure元素,不用写一长串switch判断。
  • 可以给信息容器加CSS过渡动画,让展开收起的效果更流畅。
  • 可以加加载态,接口请求过程中在容器里显示“加载中”提示,提升体验。
入门学习方向
  • 优先掌握DOM核心操作:元素选择、属性读写、class切换、内容插入、节点关系查找,接口返回的数据必须通过这些操作才能渲染到页面上。
  • 熟悉自定义data-*属性的用法,不要靠属性顺序、硬编码索引传递页面数据,容错率极低。
  • 异步请求必须加错误捕获,避免网络异常时整个页面交互崩溃。
  • 写交互前先梳理页面结构:需要展示什么内容,就先在HTML里预留对应容器,不要等拿到数据才发现没有渲染位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 21:30:22