Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么我的点击事件在生成HTML时只工作一次,而在console.logging时却正常工作?_Javascript_Html_Ajax_Dom_Events - Fatal编程技术网

Javascript 为什么我的点击事件在生成HTML时只工作一次,而在console.logging时却正常工作?

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"

它在控制台中的工作方式以及生成HTML时的工作方式,但它只在HTML中工作一次,而在控制台中始终工作。我是否需要在这里使用循环,并以这种方式返回HTML?我试过地图,但它不是数组。编辑:忘记了HTML,只是添加了它

<!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调用,以获取后端的数据。我只是想在点击正确的信息时,让背面在这一点上进行渲染。