J'ai deux boutons qui appellent la même fonction JavaScript mais avec un argument différent. Quand je les teste indépendamment, ils fonctionnent bien. Cependant, lorsqu'ils sont ensemble, seul le bouton "suivant" fonctionne. Je ne suis pas sûr de ce que je fais mal.

if (fbResults.collection.links[p].prompt == "Previous") {
    var linkBack = "" + fbResults.collection.links[p].href;
    nextBtnDiv.innerHTML += "<a id=\"prevBtn\" name=\"prevBtn\" class=\"button1\" type=\"button\">Previous</a>";
    document.getElementById("prevBtn").onclick = function () { findImages(linkBack); };
}
if (fbResults.collection.links[p].prompt == "Next") {
    var linkForward = "" + fbResults.collection.links[p].href;
    nextBtnDiv.innerHTML += "<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>";
    document.getElementById("nextBtn").onclick = function () { findImages(linkForward); };
}
1
AA24 16 mars 2019 à 09:40

2 réponses

Meilleure réponse

Vous écrasez votre premier nœud a-tag attribué :

nextBtnDiv.innerHTML += 
"<a id=\"prevBtn\" name=\"prevBtn\" class=\"button1\" type=\"button\">Previous</a>";

Crée de nouveaux nœuds. Alors à la deuxième fois

nextBtnDiv.innerHTML += 
"<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>";

C'est la même chose que

nextBtnDiv.innerHTML = 

"<a id=\"prevBtn\" name=\"prevBtn\" class=\"button1\" type=\"button\">Previous</a>" 
+ "<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>";

Mais maintenant vous supprimez le premier nœud assigné et ses écouteurs

Il est préférable de créer un nœud et de l'ajouter comme :

let a = document.createElement('a');
// set a attr ...
nextBtnDiv.appendChild(a);
1
Estradiaz 16 mars 2019 à 07:29

Une meilleure façon de le faire

Continuez à lire si vous voulez des détails sur les raisons pour lesquelles vous obtenez ce comportement. Si vous voulez une solution rapide, essayez de créer et d'ajouter des éléments DOM au lieu de manipuler directement innerHTML :

const prevBtn = document.createElement("a");
prevBtn.id = "prevBtn";
prevBtn.name = "prevBtn";
prevBtn.class = "button1";
prevBtn.type = "button";
prevBtn.innerHTML = "Previous";

const nextBtn = document.createElement("a");
nextBtn.id = "nextBtn";
nextBtn.name = "nextBtn";
nextBtn.class = "button1";
nextBtn.type = "button";
nextBtn.innerHTML = "Next";

for (let p = 0; p < 2; p++) {
  if (fbResults.collection.links[p].prompt == "Previous") {
      var linkBack = "" + fbResults.collection.links[p].href;
      prevBtn.onclick = function () { findImages(linkBack); };
      nextBtnDiv.appendChild(prevBtn);
  }
  if (fbResults.collection.links[p].prompt == "Next") {
      var linkForward = "" + fbResults.collection.links[p].href;
      nextBtn.onclick = function () { findImages(linkForward); };
      nextBtnDiv.appendChild(nextBtn);
  }
}

Pourquoi votre code se comporte comme il le fait

Quelques choses se passent ici. Premièrement, type="button" n'est pas un type valide dans une balise <a>. Il sert à décrire le type de média vers lequel vous vous connectez. Vous utiliserez donc généralement un <button> pour ce type d'appel de fonction (je suppose que c'est pour la pagination).

Deuxièmement, en jouant avec votre code, j'ai réalisé que j'avais fait une erreur que vous auriez peut-être aussi commise : j'ai donné un id="nextBtn" au <div> entourant les boutons, puis j'ai appelé la variable que j'ai trouvée en utilisant nextBtnDiv, comme vous l'avez fait. Le problème avec cela est que HTML s'attend à ce que les id soient uniques, et lorsque vous utilisez document.getElementById pour obtenir un élément dans le DOM, vous obtiendrez le premier élément qui correspond à ce id à au mieux, et au pire un comportement indéfini. Voir cette question pour plus d'informations à ce sujet .

Donc, si les deux balises d'ancrage finissent par déclencher le lien "Suivant", c'est parce que vous donnez probablement l'ensemble <div> (qui contient les deux boutons), plutôt que le bouton suivant lui-même, le gestionnaire onclick.

Enfin, si vous résolvez ce problème, vous verrez toujours que votre bouton précédent ne fait rien lorsque vous cliquez dessus. Voici pourquoi:

nextBtnDiv.innerHTML += "<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>";

Cette ligne signifie essentiellement "faire que nextBtnDiv.innerHTML soit égal à nextBtnDiv.innerHTML plus "<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>"". Le problème est un peu délicat. Il recrée les deux balises <a>, pas seulement en ajoutant la "suivante", à la <div>. C'est à cause de la sémantique += et de son fonctionnement, mais fondamentalement, une fois que vous avez de nouveaux boutons, le précédent est écrasé et vous perdez le gestionnaire onclick que vous y avez attaché.

L'un des moyens de contourner ce problème consiste à recréer le comportement de clic "précédent" une fois que vous avez créé le comportement pour le bouton "suivant". Comme dans l'extrait suivant :

const nextBtnDiv = document.getElementById("nextBtnDiv");
const fbResults = {
  collection: {
    links: [
      { prompt: "Previous", href: "previous" },
      { prompt: "Next", href: "next" },
    ],
  },
};

for (let p = 0; p < 2; p++) {
  if (fbResults.collection.links[p].prompt == "Previous") {
      var linkBack = "" + fbResults.collection.links[p].href;
      nextBtnDiv.innerHTML += "<a id=\"prevBtn\" name=\"prevBtn\" class=\"button1\" type=\"button\">Previous</a>";
      document.getElementById("prevBtn").onclick = function () { findImages(linkBack); };
  }
  if (fbResults.collection.links[p].prompt == "Next") {
      var linkForward = "" + fbResults.collection.links[p].href;
      nextBtnDiv.innerHTML += "<a id=\"nextBtn\" name=\"nextBtn\" class=\"button1\" type=\"button\" >Next</a>";
      document.getElementById("prevBtn").onclick = function () { findImages(linkBack); };
      document.getElementById("nextBtn").onclick = function () { findImages(linkForward); };
  }
}

function findImages(link) { console.log(`Clicked ${link} button`); }
<div id="nextBtnDiv"></div>
2
Bruno Ely 16 mars 2019 à 08:05