如何使用异步Fetch API将JSON文件内容解析并渲染至HTML页面
核心修改逻辑
- 若需要渲染可交互的题目单选框,需将HTML中的textarea替换为支持HTML解析的普通div容器;如果仅需要输出HTML源码,可保留textarea
- 完善Quiz类的getInfo方法,遍历选项数组生成独立的单选框元素,添加name属性保证同题选项互斥
- 遍历fetch返回的quiz数据集生成Quiz实例,拼接所有实例的getInfo返回值后插入页面
完整修改代码
HTML部分
<button id="get-text-btn">Get Data</button> <div id="loader"></div> <!-- 渲染交互题目用div,保留textarea展示源码则无需替换 --> <div id="quiz-container" style="width: 100%; margin-top: 16px;"></div>
JS部分
let button = document.getElementById("get-text-btn"); let renderContainer = document.getElementById("quiz-container"); let loader = document.getElementById("loader"); button.addEventListener("click", function () { loader.style.display = "inline-block"; getData(); }); async function getData() { try { let response = await fetch('quiz.json') if (response.status !== 200) { throw new Error("Error while reading file."); } let json = await response.json() class Quiz { constructor(question, options, questionId) { this.question = question this.options = options this.questionId = questionId } getInfo() { // 遍历生成每个选项的单选框结构 let optionsHtml = this.options.map(option => { return `<label style="display: block; margin: 8px 0;"> <input type="radio" name="${this.questionId}" value="${option}"> ${option} </label>` }).join('') // 拼接单题完整结构 return `<div class="quiz-item" style="margin: 20px 0;"> <h3>${this.question}</h3> ${optionsHtml} </div>` } } // 数据处理与渲染逻辑 let allQuizHtml = '' // 遍历所有题目生成实例 for (let qId in json.quiz) { let qData = json.quiz[qId] let quizInstance = new Quiz(qData.question, qData.options, qId) allQuizHtml += quizInstance.getInfo() } // 渲染到页面,用textarea展示源码则改为 textArea.value = allQuizHtml renderContainer.innerHTML = allQuizHtml } catch (error) { renderContainer.innerHTML = 'Fetch problem: ' + error.message; } finally { loader.style.display = "none"; } }
CSS部分
#loader { display: inline-block; width: 18px; height: 18px; display: none; } #loader:after { content: " "; display: block; width: 18px; height: 18px; margin: 2px; border-radius: 50%; border: 2px solid #241f1f; border-color: #241f1f transparent #241f1f transparent; animation: lds-dual-ring 1.2s linear infinite; } @keyframes lds-dual-ring { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
内容的提问来源于stack exchange,提问作者Dabaliu
相关产品推荐
相关产品推荐

