Hice un sitio web simple para un proyecto. Algunos de los problemas son: 1. Cuando haga clic en un país, aparecerá la bandera, haga clic nuevamente y seguirá abriendo la imagen. ¿Cómo hago para que aparezca solo una vez? 2. Una vez que hace clic en un país, aparece la información, pero cuando hace clic en otro país, el anterior permanece abierto. ¿Cómo creo un clic inverso para que solo se muestre uno a la vez? No estoy seguro de qué código necesita ver para responder esto, pero he incluido mi JavaScript por ahora. Gracias por cualquier ayuda.
var xhttp = new XMLHttpRequest(); var respJSON = []; xhttp.onreadystatechange = function () { if(this.readyState == 4 && this.status == 200) { resp = this.responseText; respJSON = JSON.parse(resp); html = document.getElementById("list"); html.innerHTML = ""; for(var i=0; i< respJSON.length; i++){ html.innerHTML += "<li id="+i+" onClick='clickMe("+i+")'>" + respJSON[i].name + "</li>" } } } xhttp.open("GET", "https://restcountries.com/v2/all", true); xhttp.send(); //create flag image on website function clickMe(index) { li = document.getElementById(index); img = document.createElement("img") img.src = respJSON[index].flag; li.append(img); let div = document.createElement("div1"); div.innerText = respJSON[index].subregion; li.append(div); }En su lugar, crea todo el contenido y oculta lo que quieras con CSS y/o JavaScript. Además, no lo use en controladores de atributos de eventos.
<li onclick="lameAttributeEventHandler()">...</li>
Detalles comentados en el siguiente ejemplo
const xhttp = new XMLHttpRequest(); // Define click handler const countryList = event => { // The <ul> const list = event.currentTarget; // All <li> of <ul> in an array const items = [...list.querySelectorAll('li')]; // The actual <li> user clicked const LI = event.target; /* if the <tag> clicked was a <li>... */ if (LI.matches('li')) { // ...remove '.on' class on all <li>... items.forEach(li => li.classList.remove('on')); // ...then add '.on' class to yje clicked <li> LI.classList.add('on'); } }; xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { let resp = this.responseText; let respJSON = JSON.parse(resp); const list = document.querySelector("ul"); list.innerHTML = ""; /* Hide content until it's needed. Create all of HTML now. */ for (var i = 0; i < respJSON.length; i++) { list.insertAdjacentHTML('beforeEnd', ` <li class='off'> <h3>${respJSON[i].name}</h3> <img src='${respJSON[i].flag}'> <p>${respJSON[i].subregion}</p> </li>`); } } }; xhttp.open("GET", "https://restcountries.com/v2/all", true); xhttp.send(); /* Do not use onEvent attribute handlers, use onEvent property handlers or eventListeners(). Because there are an unknown number of dynamically created <li>, it's easier to add the eventhandler on the <ul>. Google Event Delegation */ document.querySelector("ul").onclick = countryList; ul { list-style: none; } li { display: flex; justify-content: space-between; align-items: center; height: 40px; } .off img, .off p { visibility: hidden } h3 { pointer-events: none; } .on img, .on p { visibility: visible; } img { height: 100% } <ul></ul>Siguiendo con su problema específico, hay una cantidad de enfoques que uno podría adoptar CSS o JS. Me quedaría con el enfoque de Js por el bien de su base de código.
Ha hecho todo lo bueno que esperaba cuando ejecuta la función clickme, necesita verificar si alguna de las imágenes ya se ha agregado al DOM, si es así, luego elimínela. Sería lo primero que debe suceder y luego ir a agregar algo nuevo a dom
var xhttp = new XMLHttpRequest(); var respJSON = []; xhttp.onreadystatechange = function () { if(this.readyState == 4 && this.status == 200) { resp = this.responseText; respJSON = JSON.parse(resp); html = document.getElementById("list"); html.innerHTML = ""; for(var i=0; i< respJSON.length; i++){ html.innerHTML += "<li id="+i+" onClick='clickMe("+i+")'>" + respJSON[i].name + "</li>" } } } xhttp.open("GET", "https://restcountries.com/v2/all", true); xhttp.send(); //create flag image on website function clickMe(index) { //search and remove all image tags already inserted document.querySelectorAll('#list img').forEach( function(item) { item.remove(); }); //search and remove all div1 tags already inserted document.querySelectorAll('#list div1').forEach( function(item) { item.remove(); }); li = document.getElementById(index); img = document.createElement("img") img.src = respJSON[index].flag; li.append(img); let div = document.createElement("div1"); div.innerText = respJSON[index].subregion; li.append(div); } <ul id="list"> </ul>