我想用HTML显示一些卡片元素。我想从javascript数组中获取card元素的变量。(例如title等。)。 卡元素号还将取决于Javascript数组的大小。我看过其他问题,例如生成动态表,但是由于我有一个很长的自定义html代码块,所以它不起作用。
这是我正在建立的网站。我已经从带有HTTP get请求的api端点获取了变量,但是无法如我所愿地显示。我看过许多类似的问题,但找不到我想要的答案。
这是用于通过HTTP get请求获取变量的脚本
<script>
const request = new XMLHttpRequest();
request.open('GET', 'api/seminars', true);
request.onload = function() {
// Begin accessing JSON data here
const data = JSON.parse(this.response);
if (request.status >= 200 && request.status < 400) {
data.forEach(resultArray => {
document.getElementById('output').innerHTML = resultArray.name;
document.getElementById('description').innerHTML =
resultArray.description;
document.getElementById('date').innerHTML = resultArray.date;
});
} else {
console.log('error');
}
};
request.send();
</script>
HTML代码:
<div id="accordion">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data- target="#collapseOne" aria-expanded="true"
aria-controls="collapseOne">
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
<h5 id="name"></h5>
<p id="description"></p>
<p id="description"></p>
...
</div>
</div>
</div>
</div>
从这里开始,我继续执行不相关的html代码。
如果我的数组中有3个对象,我想创建3个不同的卡并显示名称,description ..属性。但是我的代码只能创建一张卡并显示最后一个对象的属性。
答案 0 :(得分:1)
您的代码永远不会根据您的API调用真正“创建”元素-它只会通过更新由其ID引用的固定元素的innerHTML来更新(即覆盖)现有dom元素。
如果我对您的代码的解释正确,那么您应该只会在API结果中看到LAST项目。还有其他奇怪的事情,例如重复的ID,我猜是错别字
要解决此问题,请为API返回的每个项目创建一个新的div.card-body
并将其附加到您的容器中
const apiResult = [{
title: "title1",
description: "desc1",
output: "out1"
}, {
title: "title2",
description: "desc2",
output: "out2"
}, {
title: "title3",
description: "desc3",
output: "out3"
}];
const container = document.getElementById('accordion');
apiResult.forEach((result, idx) => {
// Create card element
const card = document.createElement('div');
card.classList = 'card-body';
// Construct card content
const content = `
<div class="card">
<div class="card-header" id="heading-${idx}">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapse-${idx}" aria-expanded="true" aria-controls="collapse-${idx}">
</button>
</h5>
</div>
<div id="collapse-${idx}" class="collapse show" aria-labelledby="heading-${idx}" data-parent="#accordion">
<div class="card-body">
<h5>${result.title}</h5>
<p>${result.description}</p>
<p>${result.output}</p>
...
</div>
</div>
</div>
`;
// Append newyly created card element to the container
container.innerHTML += content;
})
.card {
padding: 1rem;
border: 1px solid black;
margin: 1rem;
}
<div id="accordion">
</div>
注意:
虽然可行,但伸缩性不是很好。有一些很棒的模板库具有更高级的插值功能,您可以考虑是否必须在许多地方做这样的事情(并进行维护)
UI框架,例如Vue,React,绑定到数据模型的Angular环绕模板,并为您处理自动更新DOM,使这种事情变得更容易。值得调查的是,如果您的网页上有很多动态更新的部分
答案 1 :(得分:1)
每次for loop
的重复执行,都将覆盖描述的innerHTML。
更改此
document.getElementById('output').innerHTML = resultArray.name;
document.getElementById('description').innerHTML = resultArray.description;
document.getElementById('date').innerHTML = resultArray.date;
对此
var element = document.createElement('div'); // create new div
var name = document.createElement('h4');
name.innerHTML = resultArray.name;
element.appendChild(name);
var description = document.createElement('p');
description.innerHTML = resultArray.description;
element.appendChild(description);
var date = document.createElement('span');
date.innerHTML = resultArray.date;
element.appendChild(date);
document.body.appendChild(element);
答案 2 :(得分:1)
假设您已经查询了API,一种实现方法可能是:
// Supposing you already have queried the API and have your data
let data = [
{name: 'name0', description: 'description', date: 'XX/XX/XXXX'},
{name: 'name1', description: 'description', date: 'XX/XX/XXXX'},
{name: 'name2', description: 'description', date: 'XX/XX/XXXX'},
]
data.forEach(res => {
let card = document.createElement("div");
let name = document.createTextNode('Name:' + res.name + ', ');
card.appendChild(name);
let description = document.createTextNode('Description:' + res.description + ', ');
card.appendChild(description);
let date = document.createTextNode('date:' + res.date);
card.appendChild(date);
let container = document.querySelector("#container");
container.appendChild(card);
});
<!-- At one point where you want to generate the cards you put this container -->
<div id="container"></div>
您无法使用,因为您总是更新相同的元素,而不是添加新元素:)