Javascript 为什么我的点击事件在生成HTML时只工作一次,而在console.logging时却正常工作?
它在控制台中的工作方式以及生成HTML时的工作方式,但它只在HTML中工作一次,而在控制台中始终工作。我是否需要在这里使用循环,并以这种方式返回HTML?我试过地图,但它不是数组。编辑:忘记了HTML,只是添加了它Javascript 为什么我的点击事件在生成HTML时只工作一次,而在console.logging时却正常工作?,javascript,html,ajax,dom,events,Javascript,Html,Ajax,Dom,Events,它在控制台中的工作方式以及生成HTML时的工作方式,但它只在HTML中工作一次,而在控制台中始终工作。我是否需要在这里使用循环,并以这种方式返回HTML?我试过地图,但它不是数组。编辑:忘记了HTML,只是添加了它 <!DOCTYPE html> <html> <head> <title>Pokedex</title> <link rel="stylesheet" type="text/css" href="styles.css"
<!DOCTYPE html>
<html>
<head>
<title>Pokedex</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<h1 id="main-header">Pokedex</h1>
<div id="main-container">
</div>
<script src="index.js" type="text/javascript"></script>
</body>
</html>
Pokedex
Pokedex
Javascript
const container = document.getElementById('main-container');
function getPokemon(callback) {
const xhr = new XMLHttpRequest();
const url = 'https://pokeapi.co/api/v2/pokemon/';
xhr.onload = function() {
if(xhr.status === 200) {
const pokemon = JSON.parse(xhr.responseText);
container.innerHTML+=
pokemon.results.map((poke, index)=>{
return `
<div class='cardFront'>
<img src='https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${(index + 1).toString()}.png'></img>
<h4>${poke.name}</h4>
</div>
`
}).join('');
callback();
}
}
xhr.open('GET', url, true);
xhr.send();
}
function cardBack() {
const endPoint = this.lastChild.previousSibling.innerText;
const xhr = new XMLHttpRequest();
xhr.onload = function() {
if(xhr.status === 200) {
const details = JSON.parse(xhr.responseText);
container.innerHTML+= `
<div class='backSide'>
<h4>${details.name}</h4>
<h4>${details.types[0].type.name}</h4>
</div>
`
}
}
xhr.open('GET', 'https://pokeapi.co/api/v2/pokemon/' + endPoint, true);
xhr.send();
}
getPokemon(()=>{
const cardFront = document.querySelectorAll('.cardFront');
cardFront.forEach((card)=> {
card.addEventListener('click', cardBack);
})
});
const container=document.getElementById('main-container');
函数getPokemon(回调){
const xhr=new XMLHttpRequest();
常量url=https://pokeapi.co/api/v2/pokemon/';
xhr.onload=函数(){
如果(xhr.status==200){
const pokemon=JSON.parse(xhr.responseText);
container.innerHTML+=
pokemon.results.map((poke,index)=>{
返回`
${poke.name}
`
}).加入(“”);
回调();
}
}
xhr.open('GET',url,true);
xhr.send();
}
函数cardBack(){
const endPoint=this.lastChild.previousSibling.innerText;
const xhr=new XMLHttpRequest();
xhr.onload=函数(){
如果(xhr.status==200){
const details=JSON.parse(xhr.responseText);
container.innerHTML+=`
${details.name}
${details.types[0].type.name}
`
}
}
xhr.open('GET','https://pokeapi.co/api/v2/pokemon/“+端点,正确);
xhr.send();
}
getPokemon(()=>{
const cardFront=document.queryselectoral('.cardFront');
cardFront.forEach((卡)=>{
card.addEventListener(“单击”,回拨);
})
});
在click listener的回调函数中,您正在使用其.innerHTML属性向主容器
元素添加新的html代码。
这将删除所有现有的事件侦听器-因此单击只会触发一次
尽管我建议使用
var newDiv=document.createElement(“DIV”)代码>
并通过以下方式将其附加到主容器中:
document.getElementById('main-container').appendChild(newDiv)代码>
在您的案例中,更简单的解决方案是替换
container.innerHTML+= `
<div class='backSide'>
<h4>${details.name}</h4>
<h4>${details.types[0].type.name}</h4>
</div>
`
container.innerHTML+=`
${details.name}
${details.types[0].type.name}
`
借
container.insertAdjacentHTML(“afterend”`
${details.name}
${details.types[0].type.name}
`);
在click listener的回调函数中,您正在使用其.innerHTML属性向主容器
元素添加新的html代码。
这将删除所有现有的事件侦听器-因此单击只会触发一次
尽管我建议使用
var newDiv=document.createElement(“DIV”)代码>
并通过以下方式将其附加到主容器中:
document.getElementById('main-container').appendChild(newDiv)代码>
在您的案例中,更简单的解决方案是替换
container.innerHTML+= `
<div class='backSide'>
<h4>${details.name}</h4>
<h4>${details.types[0].type.name}</h4>
</div>
`
container.innerHTML+=`
${details.name}
${details.types[0].type.name}
`
借
container.insertAdjacentHTML(“afterend”`
${details.name}
${details.types[0].type.name}
`);
我创建了一个似乎符合所有标准的版本。只有在单击卡后才会请求回卡信息,并且可以再次单击该卡返回到前面。我通过在同一个div中构建每个卡的正面和背面,并在两面之间切换一个“隐藏”类来实现这一点
我通常使用fetch()和promissions,但使用xhr和回调保留您的原始代码
代码笔在这里:
JS
const container = document.getElementById('main-container');
const pokeNames = [];
let loading = false;
function getPokemon(callback) {
const xhr = new XMLHttpRequest();
const url = 'https://pokeapi.co/api/v2/pokemon/';
xhr.onload = function () {
if (xhr.status === 200) {
const pokemon = JSON.parse(xhr.responseText);
container.innerHTML +=
pokemon.results.map((poke, index) => {
const pokeName = poke.name.replace(/\s/g, "");
pokeNames.push(poke.name);
return `
<div id="poke-${pokeName}" class="poke-card">
<div class='cardFront'>
<img src='https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${(index + 1).toString()}.png'></img>
<h4>${pokeName}</h4>
</div>
</div>
`
}).join('');
callback();
}
}
xhr.open('GET', url, true);
xhr.send();
}
function addCardBack(pokeName, callback) {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status === 200) {
const details = JSON.parse(xhr.responseText);
const pokeContainer = document.getElementById(`poke-${pokeName}`);
pokeContainer.innerHTML += `
<div class='cardBack'>
<h4>${details.name}</h4>
<h4>${details.types[0].type.name}</h4>
</div>
`;
callback(pokeName);
}
loading = false;
}
loading = true;
xhr.open('GET', 'https://pokeapi.co/api/v2/pokemon/' + pokeName, true);
xhr.send();
}
function toggleCard(pokeName) {
const cardBack = document.querySelectorAll(`#poke-${pokeName} .cardBack`)[0];
if (!cardBack) {
// Prevent a second click from calling this function again before data is loaded
if (!loading) {
addCardBack(pokeName, (pokeName) => {
swapCards(pokeName);
});
}
} else {
swapCards(pokeName);
}
}
function swapCards(pokeName) {
const cardFront = document.querySelectorAll(`#poke-${pokeName} .cardFront`)[0];
const cardBack = document.querySelectorAll(`#poke-${pokeName} .cardBack`)[0];
if (cardFront.classList.contains('hidden')) {
cardFront.classList.remove('hidden');
cardBack.classList.add('hidden');
} else {
cardFront.classList.add('hidden');
cardBack.classList.remove('hidden');
}
}
getPokemon(() => {
pokeNames.forEach((pokeName) => {
const card = document.getElementById(`poke-${pokeName}`);
card.addEventListener('click', () => toggleCard(pokeName));
})
});
.hidden {
display: none;
}
.poke-card {
width: 100px;
height: 150px;
padding: 10px;
margin-bottom: 20px;
border: 1px solid blue;
}
我创建了一个似乎符合所有标准的版本。只有在单击卡后才会请求回卡信息,并且可以再次单击该卡返回到前面。我通过在同一个div中构建每个卡的正面和背面,并在两面之间切换一个“隐藏”类来实现这一点
我通常使用fetch()和promissions,但使用xhr和回调保留您的原始代码
代码笔在这里:
JS
const container = document.getElementById('main-container');
const pokeNames = [];
let loading = false;
function getPokemon(callback) {
const xhr = new XMLHttpRequest();
const url = 'https://pokeapi.co/api/v2/pokemon/';
xhr.onload = function () {
if (xhr.status === 200) {
const pokemon = JSON.parse(xhr.responseText);
container.innerHTML +=
pokemon.results.map((poke, index) => {
const pokeName = poke.name.replace(/\s/g, "");
pokeNames.push(poke.name);
return `
<div id="poke-${pokeName}" class="poke-card">
<div class='cardFront'>
<img src='https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${(index + 1).toString()}.png'></img>
<h4>${pokeName}</h4>
</div>
</div>
`
}).join('');
callback();
}
}
xhr.open('GET', url, true);
xhr.send();
}
function addCardBack(pokeName, callback) {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status === 200) {
const details = JSON.parse(xhr.responseText);
const pokeContainer = document.getElementById(`poke-${pokeName}`);
pokeContainer.innerHTML += `
<div class='cardBack'>
<h4>${details.name}</h4>
<h4>${details.types[0].type.name}</h4>
</div>
`;
callback(pokeName);
}
loading = false;
}
loading = true;
xhr.open('GET', 'https://pokeapi.co/api/v2/pokemon/' + pokeName, true);
xhr.send();
}
function toggleCard(pokeName) {
const cardBack = document.querySelectorAll(`#poke-${pokeName} .cardBack`)[0];
if (!cardBack) {
// Prevent a second click from calling this function again before data is loaded
if (!loading) {
addCardBack(pokeName, (pokeName) => {
swapCards(pokeName);
});
}
} else {
swapCards(pokeName);
}
}
function swapCards(pokeName) {
const cardFront = document.querySelectorAll(`#poke-${pokeName} .cardFront`)[0];
const cardBack = document.querySelectorAll(`#poke-${pokeName} .cardBack`)[0];
if (cardFront.classList.contains('hidden')) {
cardFront.classList.remove('hidden');
cardBack.classList.add('hidden');
} else {
cardFront.classList.add('hidden');
cardBack.classList.remove('hidden');
}
}
getPokemon(() => {
pokeNames.forEach((pokeName) => {
const card = document.getElementById(`poke-${pokeName}`);
card.addEventListener('click', () => toggleCard(pokeName));
})
});
.hidden {
display: none;
}
.poke-card {
width: 100px;
height: 150px;
padding: 10px;
margin-bottom: 20px;
border: 1px solid blue;
}
你的html在哪里?这是一个你想点击的动态按钮?@User1899289003这是一张口袋妖怪卡。我已经渲染了前端,然后对另一个端点进行API调用,以获取后端的数据。我只是想在点击正确的信息时让背面呈现。你的html在哪里?这是一个动态按钮,你想点击它?@User1899289003这是一张口袋妖怪卡。我已经渲染了前端,然后对另一个端点进行API调用,以获取后端的数据。我只是想在点击正确的信息时,让背面在这一点上进行渲染。