PHP项目:JSON人员数据展示的视图切换功能实现求助
问题描述
我需要开发一个程序,实现从JSON文件读取人员数据并展示的功能:默认视图只显示人员姓名,点击任意一项后切换为该人员的完整信息(姓名、电话、邮箱)。目前无法实现视图切换,以下是我的代码:
HTML代码
<html> <head> <link rel="stylesheet" type="text/css" href="style.css"> <script type="text/javascript" src="skript.js"></script> <title>Main</title> </head> <body> <header> <h1>Main</h1> </header> </nav> <main class="view"> </main> </body> </html>
JS代码
fetch('data.json') .then(response => response.json()) .then(data => createListContact(data)); /** * Function to display as a list data.json */ function createListContact(data) { // create ol for all persons const ol = document.createElement('ol'); ol.classList.add("list-view"); // for each person one li for (let i = 0; i < data.personen.length; i++) { const li = document.createElement('li'); li.classList.add("button"); li.setAttribute("id", i+1); li.innerHTML ='Name: '+ data.personen[i].nachname + ', ' + data.personen[i].vorname; ol.appendChild(li); document.body.appendChild(ol); } } /* * Function adds event listener to li element */ function eventListener (){ const liElements = document.getElementsByTagName("li"); for (let li of liElements){ li.addEventListener("click",() => showDetails(li)); } } /** * Function to open detailed info * * @param li element to show details from */ function showDetails(li){ var details = document.createElement('div'); details.className = 'details'; details.id ="test"; var close = document.createElement('div'); close.className= 'close'; close.innerHTML= 'close'; close.onclick = function(e) { details.parentNode.removeChild(details)}; var info = document.createElement('li'); info.innerHTML = 'Name: '+ data.personen[i].nachname + ', ' + data.personen[i].vorname + 'Tel.: '+ data.personen[i].telefonnummer+ 'E-mail: '+data.personen[i].email; details.appendChild(info); details.appendChild(schließen); document.body.appendChild(details); }
CSS代码
body { background-color: #886b6b77; } p { color: #333; font-family: "Times New Roman", Times, serif; font-size: 20px; text-align: center; } textarea { font-family: inherit; } form { border: 1px solid black; width: 90%; background-color: whitesmoke; margin: 0 auto; padding: 0 1em; } form label { display: block; font-size: 0.8em; color: darkslategrey; padding-left: 3px; } input, textarea { width: 100%; font-size: 1.1em; padding: 4px; font-family: inherit; font-weight: lighter; border:1px solid gray; outline: none; border-radius: 0.3em; } input:focus, textarea:focus { border:1px solid orange; } input[type=submit] { background-color: #ffffff77; cursor: pointer; width: 14em; padding: .3em 0; border-radius: 0.7em; margin-bottom: 1em; } input[type=submit]:hover { background-color: rgb(59, 58, 58); box-shadow: 2px 2px 2px grey; } ul { list-style-type: none; margin: 0; padding: 0; overflow: hidden; background-color: #333; margin-bottom: 1em; } ul li { float: left; } li a { display: block; color: white; text-align: center; padding: 14px 16px; text-decoration: none; } ol{ list-style-type: none; text-align: center; color: white; } /* Change the link color to #111 (black) on hover */ li a:hover { background-color: #111; } img{ display: block; margin-left: auto; margin-right: auto; width: 50%; } #wahl{ margin-top: 1em; margin-bottom: 0.5em; } #button_load{ margin-bottom: 1em; } /* * list-view */ .list-view .button { cursor: pointer; background: none; font-size: 20px; color: white; font-family: "Times New Roman", Times, serif; } .list-view .button:hover{ background-color: #333; }
问题修复方案
核心问题梳理
- 事件监听器未触发:
eventListener()函数仅定义未调用,导致点击事件未绑定。 - 数据作用域失效:
showDetails无法访问createListContact内的data和i变量。 - DOM重复插入:循环内多次将
<ol>插入body,应该循环结束后统一插入。 - 变量名错误:
schließen应为close。 - 视图切换逻辑缺失:未隐藏列表视图,仅追加详情元素。
修复后的完整代码
HTML(修正多余标签)
<html> <head> <link rel="stylesheet" type="text/css" href="style.css"> <script type="text/javascript" src="skript.js"></script> <title>Main</title> </head> <body> <header> <h1>Main</h1> </header> <nav></nav> <main class="view"> </main> </body> </html>
JS(修复所有问题)
// 全局存储人员数据,方便详情函数访问 let personData = []; fetch('data.json') .then(response => response.json()) .then(data => { personData = data.personen; createListContact(data); // 创建列表后立即绑定事件 eventListener(); }); /** * 生成人员列表视图 */ function createListContact(data) { const ol = document.createElement('ol'); ol.classList.add("list-view"); for (let i = 0; i < data.personen.length; i++) { const li = document.createElement('li'); li.classList.add("button"); // 存储索引,方便后续获取对应数据 li.dataset.index = i; li.innerHTML = `Name: ${data.personen[i].nachname}, ${data.personen[i].vorname}`; ol.appendChild(li); } // 循环结束后统一插入到main容器 document.querySelector('.view').appendChild(ol); } /** * 为列表项绑定点击事件 */ function eventListener (){ const liElements = document.querySelectorAll(".list-view .button"); liElements.forEach(li => { li.addEventListener("click", () => showDetails(li)); }); } /** * 显示人员详情视图 */ function showDetails(li){ // 获取当前项对应的人员索引 const index = parseInt(li.dataset.index); const person = personData[index]; // 清空main容器,切换视图 const main = document.querySelector('.view'); main.innerHTML = ''; // 创建详情容器 const details = document.createElement('div'); details.className = 'details'; // 创建返回按钮 const backBtn = document.createElement('button'); backBtn.className = 'back-btn'; backBtn.textContent = '返回列表'; backBtn.addEventListener('click', () => { main.innerHTML = ''; createListContact({personen: personData}); eventListener(); }); // 创建详情内容 const info = document.createElement('div'); info.innerHTML = ` <h2>${person.nachname}, ${person.vorname}</h2> <p>Tel.: ${person.telefonnummer}</p> <p>E-mail: ${person.email}</p> `; details.appendChild(backBtn); details.appendChild(info); main.appendChild(details); }
CSS(新增详情视图样式)
body { background-color: #886b6b77; } p { color: #333; font-family: "Times New Roman", Times, serif; font-size: 20px; text-align: center; } textarea { font-family: inherit; } form { border: 1px solid black; width: 90%; background-color: whitesmoke; margin: 0 auto; padding: 0 1em; } form label { display: block; font-size: 0.8em; color: darkslategrey; padding-left: 3px; } input, textarea { width: 100%; font-size: 1.1em; padding: 4px; font-family: inherit; font-weight: lighter; border:1px solid gray; outline: none; border-radius: 0.3em; } input:focus, textarea:focus { border:1px solid orange; } input[type=submit] { background-color: #ffffff77; cursor: pointer; width: 14em; padding: .3em 0; border-radius: 0.7em; margin-bottom: 1em; } input[type=submit]:hover { background-color: rgb(59, 58, 58); box-shadow: 2px 2px 2px grey; } ul { list-style-type: none; margin: 0; padding: 0; overflow: hidden; background-color: #333; margin-bottom: 1em; } ul li { float: left; } li a { display: block; color: white; text-align: center; padding: 14px 16px; text-decoration: none; } ol{ list-style-type: none; text-align: center; color: white; padding: 0; } /* Change the link color to #111 (black) on hover */ li a:hover { background-color: #111; } img{ display: block; margin-left: auto; margin-right: auto; width: 50%; } #wahl{ margin-top: 1em; margin-bottom: 0.5em; } #button_load{ margin-bottom: 1em; } /* * list-view */ .list-view .button { cursor: pointer; background: none; font-size: 20px; color: white; font-family: "Times New Roman", Times, serif; padding: 8px 0; border-bottom: 1px solid rgba(255,255,255,0.2); } .list-view .button:hover{ background-color: #333; } /* * 详情视图样式 */ .details { background-color: rgba(255,255,255,0.9); padding: 2em; border-radius: 8px; max-width: 600px; margin: 2em auto; color: #333; } .back-btn { background-color: #333; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; margin-bottom: 1em; } .back-btn:hover { background-color: #111; } .details h2 { font-family: "Times New Roman", Times, serif; margin-bottom: 1em; } .details p { text-align: left; margin: 0.5em 0; }
关键修改说明
- 全局存储数据:用
personData变量存储人员数据,让showDetails能访问到完整信息。 - 绑定事件时机:在
fetch回调中创建列表后立即调用eventListener,确保事件绑定有效。 - 存储索引:给列表项添加
data-index属性,点击时能快速定位到对应人员数据。 - 视图切换逻辑:点击列表项时清空
main容器,替换为详情内容;点击返回按钮时重新渲染列表。 - 修复DOM插入错误:循环内只创建列表项,循环结束后将整个
<ol>插入到main容器。 - 新增详情样式:添加详情视图的CSS,提升页面美观度。
内容的提问来源于stack exchange,提问作者Miakosa
相关产品推荐
相关产品推荐

