Así que necesito que se muestre una imagen promocional como un banner en una página. Tengo 4 botones debajo de dicho banner. Cada botón corresponde con un banner de imagen promocional diferente.

Me gustaría usar un eventlistener con la función de clic para mostrar cada imagen correspondiente, pero solo una a la vez. Este es el javascript que intenté usar, pero no parece estar funcionando.

var btn1 = document.getElementById("promo_button1");
var btn2 = document.getElementById("promo_button2");
var btn3 = document.getElementById("promo_button3");
var btn4 = document.getElementById("promo_button4");

var img1 = document.getElementById("promo1");
var img2 = document.getElementById("promo2");
var img3 = document.getElementById("promo3");
var img4 = document.getElementById("promo4");

var imgArray = [img1, img2, img3, img4];

function showImg(img) {
  for (i = 0; i < imgArray.length; i++) {
    imgArray[i].style.display = "none";
  }
  img.style.display = "block";
}


btn1.addEventListener("click", function() {
  showImg(img1);
});
btn2.addEventListener("click", function() {
  showImg(img2);
});
btn3.addEventListener("click", function() {
  showImg(img3);
});
btn4.addEventListener("click", function() {
  showImg(img4);
});
<div class="section group">
  <div class="col span_1_of_6">
  </div>
  <div class="col span_4_of_6">
    <div class="promo" id="promo1">
      <a href="cat_suits.html" border="0"><img src="img/banner_suits.jpg" alt="Suits on sale!" /></a>
    </div>
    <div class="promo" id="promo2" style="display:none">
      <a href="cat_suits.html" border="0"><img src="img/banner_shoes.jpg" alt="Shoes on sale!" /></a>
    </div>
    <div class="promo" id="promo3" style="display:none">
      <a href="cat_suits.html" border="0"><img src="img/banner_shirts.jpg" alt="Shirts on sale!" /></a>
    </div>
    <div class="promo" id="promo4" style="display:none">
      <a href="cat_suits.html" border="0"><img src="img/banner_pants.jpg" alt="Pants on sale!" /></a>
    </div>
  </div>
  <div class="col span_1_of_6">
  </div>

  <div class="section group">
    <div class="col span_1_of_6">
    </div>
    <div class="col span_1_of_6">
      <a href="">
        <div class="promo_button" id="promo_button1">
          Suits
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
      <a href="">
        <div class="promo_button" id="promo_button2">
          Shoes
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
      <a href="">
        <div class="promo_button" id="promo_button3">
          Shirts
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
      <a href="">
        <div class="promo_button" id="promo_button4">
          Pants
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
    </div>
  </div>
</div>
0
louisebelcher 4 mar. 2018 a las 09:38

4 respuestas

La mejor respuesta

Bueno, su código está funcionando bien, es solo el a que tiene envolviendo todo el <div class="promo_button" tiene un href="" en blanco que está causando este problema.

Entonces, en lugar de mantener href="", lo que está causando una redirección de página, debe tener href="#" y onclick, puede simplemente return false.

var btn1 = document.getElementById("promo_button1");
var btn2 = document.getElementById("promo_button2");
var btn3 = document.getElementById("promo_button3");
var btn4 = document.getElementById("promo_button4");

var img1 = document.getElementById("promo1");
var img2 = document.getElementById("promo2");
var img3 = document.getElementById("promo3");
var img4 = document.getElementById("promo4");

var imgArray = [img1, img2, img3, img4];

function showImg(img) {
  for (i = 0; i < imgArray.length; i++) {
    imgArray[i].style.display = "none";
  }
  img.style.display = "block";
}


btn1.addEventListener("click", function(e) {
  showImg(img1);
});
btn2.addEventListener("click", function(e) {
  showImg(img2);
});
btn3.addEventListener("click", function(e) {
  showImg(img3);
});
btn4.addEventListener("click", function(e) {
  showImg(img4);
});
<div class="section group">
  <div class="col span_1_of_6">
  </div>
  <div class="col span_4_of_6">
    <div class="promo" id="promo1">
      <a href="cat_suits.html" border="0"><img src="img/banner_suits.jpg" alt="Suits on sale!" /></a>
    </div>
    <div class="promo" id="promo2" style="display:none">
      <a href="cat_suits.html" border="0"><img src="img/banner_shoes.jpg" alt="Shoes on sale!" /></a>
    </div>
    <div class="promo" id="promo3" style="display:none">
      <a href="cat_suits.html" border="0"><img src="img/banner_shirts.jpg" alt="Shirts on sale!" /></a>
    </div>
    <div class="promo" id="promo4" style="display:none">
      <a href="cat_suits.html" border="0"><img src="img/banner_pants.jpg" alt="Pants on sale!" /></a>
    </div>
  </div>
  <div class="col span_1_of_6">
  </div>

  <div class="section group">
    <div class="col span_1_of_6">
    </div>
    <div class="col span_1_of_6">
      <a href="#" onclick="return false;">
        <div class="promo_button" id="promo_button1">
          Suits
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
      <a href="#" onclick="return false;">
        <div class="promo_button" id="promo_button2">
          Shoes
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
      <a href="#" onclick="return false;">
        <div class="promo_button" id="promo_button3">
          Shirts
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
      <a href="#"  onclick="return false;">
        <div class="promo_button" id="promo_button4">
          Pants
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
    </div>
  </div>
</div>
2
void 4 mar. 2018 a las 06:45

Debe evitar la acción predeterminada de la etiqueta de anclaje, escribir el ancla href="" no es correcto. Puedes hacer uso de href="javascript:void(0);"

La razón por la que desea hacer esto con el href de un enlace es que normalmente, una URL javascript: redirigirá el navegador a una versión de texto sin formato del resultado de evaluar ese JavaScript. Pero si el resultado es undefined, el navegador permanece en la misma página. void(0) es solo un script corto y simple que se evalúa como undefined.

var btn1 = document.getElementById("promo_button1");
var btn2 = document.getElementById("promo_button2");
var btn3 = document.getElementById("promo_button3");
var btn4 = document.getElementById("promo_button4");

var img1 = document.getElementById("promo1");
var img2 = document.getElementById("promo2");
var img3 = document.getElementById("promo3");
var img4 = document.getElementById("promo4");

var imgArray = [img1, img2, img3, img4];

function showImg(img) {
  for (i = 0; i < imgArray.length; i++) {
    imgArray[i].style.display = "none";
  }
  img.style.display = "block";
}


btn1.addEventListener("click", function() {
  showImg(img1);
});
btn2.addEventListener("click", function() {
  showImg(img2);
});
btn3.addEventListener("click", function() {
  showImg(img3);
});
btn4.addEventListener("click", function() {
  showImg(img4);
});
<div class="section group">
  <div class="col span_1_of_6">
  </div>
  <div class="col span_4_of_6">
    <div class="promo" id="promo1">
      <a href="cat_suits.html" border="0"><img src="img/banner_suits.jpg" alt="Suits on sale!" /></a>
    </div>
    <div class="promo" id="promo2" style="display:none">
      <a href="cat_suits.html" border="0"><img src="img/banner_shoes.jpg" alt="Shoes on sale!" /></a>
    </div>
    <div class="promo" id="promo3" style="display:none">
      <a href="cat_suits.html" border="0"><img src="img/banner_shirts.jpg" alt="Shirts on sale!" /></a>
    </div>
    <div class="promo" id="promo4" style="display:none">
      <a href="cat_suits.html" border="0"><img src="img/banner_pants.jpg" alt="Pants on sale!" /></a>
    </div>
  </div>
  <div class="col span_1_of_6">
  </div>

  <div class="section group">
    <div class="col span_1_of_6">
    </div>
    <div class="col span_1_of_6">
      <a href="javascript:void(0);">
        <div class="promo_button" id="promo_button1">
          Suits
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
      <a href="javascript:void(0);">
        <div class="promo_button" id="promo_button2">
          Shoes
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
      <a href="javascript:void(0);">
        <div class="promo_button" id="promo_button3">
          Shirts
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
      <a href="javascript:void(0);">
        <div class="promo_button" id="promo_button4">
          Pants
        </div>
      </a>
    </div>
    <div class="col span_1_of_6">
    </div>
  </div>
</div>
0
Shubham Khatri 4 mar. 2018 a las 07:56

Primero, reduje su código a lo que llamamos un MCVE en StackOverflow (eliminé todo el código que no estaba directamente relacionado con el problema) .

En segundo lugar, me deshice de todos los atributos id que usó, no son necesarios.

En tercer lugar, para que se pueda ver algo, reemplacé sus imágenes locales por ositos de posición.

Esto es lo que se me ocurriría:

// create an array holding the img DOM objects
let images = Array.from(document.querySelectorAll('.promo'));

// create an array from the buttons and iterate over it, 
// passing each button (as btn) and the index (as index)
// into each iteration
Array.from(document.querySelectorAll('.promo_button')).forEach((btn, index) => {
  // add a click event listener to the button
  btn.addEventListener('click', () => {
    // on click of a button, iterate over the images
    images.forEach((img, idx) => {
      // change style property of img to 
      // - none if the index of the image does not
      //   match the index of the button clicked
      // - block if both indexes match
      img.style.display = (index === idx ? 'block' : 'none');
      // using a ternary expression, which does the same as
      // if (index === idx) {
      //   img.style.display = 'block';
      // } else {
      //   img.style.display = 'none';
      // }
    })
  })
})
<img src="https://placebear.com/200/300" alt="bear 1" class="promo" />
<img src="https://placebear.com/300/300" alt="bear 2" class="promo" style="display:none" />
<img src="https://placebear.com/300/200" alt="bear 3" class="promo" style="display:none" />
<img src="https://placebear.com/200/200" alt="bear 4" class="promo" style="display:none" />
<hr />
<button class="promo_button">Suits</button>
<button class="promo_button">Shoes</button>
<button class="promo_button">Shirts</button>
<button class="promo_button">Pants</button>

Este mismo Javascript también funcionaría para un número arbitrario de imágenes y el número correspondiente de botones. Sería aún más elegante agregar los botones mediante programación:

let images = Array.from(document.querySelectorAll('.promo'));

// for each image, create a button to show it
// and outright attach the click handler to each button
images.forEach((img, index) => {
  let btn = document.createElement('button');
  let btnText = document.createTextNode(img.getAttribute('alt'));
  btn.appendChild(btnText);
  btn.classList.add('promo_button');
  btn.addEventListener('click', () => {
    images.forEach((img, idx) => {
      img.style.display = (index === idx ? 'block' : 'none');
    })
  })
  document.body.append(btn);
})
<img src="https://placebear.com/200/300" alt="bear 1" class="promo" />
<img src="https://placebear.com/300/300" alt="bear 2" class="promo" style="display:none" />
<img src="https://placebear.com/300/200" alt="bear 3" class="promo" style="display:none" />
<img src="https://placebear.com/200/200" alt="bear 4" class="promo" style="display:none" />
<hr />

Editar

Acabo de ver que estás haciendo esto para una clase de diseño web. Dependiendo del conocimiento de su maestro, este código Javascript puede ser demasiado avanzado para ellos. Si necesita más explicaciones sobre lo que está sucediendo en línea ... solo pregunte.

0
connexo 4 mar. 2018 a las 07:57

Su problema inicial estaba en su HTML con la etiqueta de ancla que rodea los elementos .promo_button. El atributo href de la etiqueta de anclaje se estableció en una cadena vacía, "".

Algunas sugerencias: evitaría poner estilos en línea en su HTML tanto como sea posible porque pueden ser difíciles de localizar a medida que su proyecto crece. También document.querySelector y document.querySelectorAll son una mejor solución que document.getElementByXXX cuando necesita hacer referencia a un grupo de elementos HTML relacionados. Dado que document.querySelectorAll asigna los elementos a una matriz NodeList, puede acceder a cada elemento sin tener que asignar ID en HTML o nombres de variables individuales en JavaScript. Puede hacer lo mismo con HTMLCollections, pero sus limitaciones son mayores en mi opinión.

/*Assign .promo_button elements to a NodeList(Array-like)*/
var btn_list = document.querySelectorAll('.promo_button');


/*Assign .promo elements to a NodeList(Array-like)*/
var img_list = document.querySelectorAll('.promo');


/*Displays image associated with button pressed, hides other images
  Assumes image and its corresponding button will be at same index
*/
function showImg() {
  //for...of is ES6, a simple forloop can also do the trick but requires more code
  //.entries allows you to access key/value pairs of the NodeList
  for (var [index, btn] of btn_list.entries()) {
    img_list[index].style.display = "none";
    if (btn == document.activeElement) {
      img_list[index].style.display = 'block';
    }
  }
}

/*Assign click listener to .promo_button elements*/
for (btn of btn_list) {
  btn.onclick = showImg;
}
.promo {
  display: none;
  /*hides all images when page loads*/
  border: 0;
}


/*displays first image when page loads*/

.promo:nth-of-type(1) {
  display: block;
}


/*sets fixed dimensions on images*/

.promo a img {
  height: 100px;
  width: 60px;
}

.promo_button {
  min-width: 60px;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>

<!-- HTML CHANGES: added links to image tag's src attribute, removed inline styles  -->  
  
<div class="section group">
  <div class="col span_1_of_6">
  </div>
  <div class="col span_4_of_6">
    <div class="promo" id="promo1">
      <a href="cat_suits.html" ><img src="https://media.istockphoto.com/photos/unrecognizable-businessman-in-a-classical-suit-picture-id496312478?k=6&m=496312478&s=612x612&w=0&h=wV0lxNsnG6XMW4uIKL89HQD3A9LNFKhalhpb05auVR0=" alt="Suits on sale!" /></a>
    </div>
    <div class="promo" id="promo2">
      <a href="cat_suits.html" ><img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcStxa8Lo2sWRpgR2klGQiR_YeLtumUBaSdCWHQNw1ciOdiP1HBAEw" alt="Shoes on sale!" /></a>
    </div>
    <div class="promo" id="promo3">
      <a href="cat_suits.html" ><img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSKKe0BOy0ulsoKUMo6DyHXBdoomNx_ZH7aCTsX-QS2Ilo0uPO5" alt="Shirts on sale!" /></a>
    </div>
    <div class="promo" id="promo4">
      <a href="cat_suits.html" ><img src="https://thumb1.shutterstock.com/display_pic_with_logo/2746450/512816923/stock-photo-brown-pants-512816923.jpg" alt="Pants on sale!" /></a>
    </div>
  </div>
  <div class="col span_1_of_6">
  </div>
 
  <!-- HTML CHANGES: Added button tags instead of div tags, remove IDs, added dead link(#) to Anchor tags to prevent leaving page when button clicked  -->
  
  <div class="section group">
    <div class="col span_1_of_6">
    </div>
    <div class="col span_1_of_6">
      <a href="#">
        <button class="promo_button" >
          Suits
        </button>
      </a>
    </div>
    <div class="col span_1_of_6">
      <a href="#">
        <button class="promo_button" >
          Shoes
        </button>
      </a>
    </div>
    <div class="col span_1_of_6">
      <a href="#">
        <button class="promo_button" >
          Shirts
        </button>
      <!-- </a> -->
    </div>
    <div class="col span_1_of_6">
      <a href="#">
        <button class="promo_button">
          Pants
        </button>
      </a>
    </div>
    <div class="col span_1_of_6">
    </div>
  </div>
</div>
</body>
</html>
0
HelloWorldPeace 4 mar. 2018 a las 10:23