Hice un pequeño diseño con círculos que se expanden al hacer clic en ellos. Tengo varios círculos y quiero poder hacer clic y expandirme en un círculo a la vez y luego se cierra el otro círculo.

Aquí hay un codeply de mi ejemplo: https://www.codeply.com/p/7QdDsEF9ul

Y aquí está el fragmento de jQuery:

$('.product1').click(function () {
$('#product1').toggleClass('expand');
$('.hidden#1').toggleClass('show');

$('.hidden#2').removeClass('show');
$('#product2').removeClass('expand');
});

$('.product2').click(function () {
$('#product2').toggleClass('expand');
$('.hidden#2').toggleClass('show');
});

Como puede ver, esto no será muy eficiente, especialmente si agrego más círculos. ¿Hay una manera más fácil de hacer esto?

0
Mark 24 abr. 2020 a las 03:42

2 respuestas

Dado que el div que debe mostrarse es un descendiente del .circle que tiene su clase cambiada cuando se muestra, puede evitar tener que jugar con el div hijo mediante la regla CSS .expand div en lugar. De esta manera, los cambios en el padre con .expand serán suficientes.

Dele a todos los <a> s una clase común, tal vez product, y al hacer clic, verifique si su hijo (el .circle) tiene la clase expand o no. Si es así, elimine .expand de todos elementos; de lo contrario, elimine expand de todos los elementos pero luego agréguelo a .circle niño:

$('.product').click(function() {
  const $circle = $(this).children();
  if ($circle.hasClass('expand')) {
    $('.expand').removeClass('expand');
  } else {
    $('.expand').removeClass('expand');
    $circle.addClass('expand');
  }
});
a {
  font-size: 2.25em;
}

.active {
  color: #6bd627;
}

.circle {
  width: 150px;
  height: 150px;
  background-color: #00aae8;
  border-radius: 50%;
  justify-content: center;
  align-items: center;
  display: flex;
  transition: all 0.3s ease-in-out;
  position: absolute;
}

.circle h2 {
  color: #fff;
  font-size: 0.7em;
  margin-bottom: auto;
  margin-top: 55px;
}

.expand {
  height: 248px !important;
  background-color: #6bd627 !important;
  border-top-left-radius: 50%;
  border-top-right-radius: 50%;
  border-bottom-left-radius: 0%;
  border-bottom-right-radius: 0%;
  transition: all 0.3s ease-in-out;
  position: absolute;
}

.hidden {
  display: none;
  opacity: 0;
  transition: all 0.3s ease-in-out;
}

.expand div {
  display: block !important;
  position: absolute;
  opacity: 1;
  transition: all 0.3s ease-in-out;
}

.link {
  font-size: 0.5em;
  color: #000;
}

ul,
ol {
  margin: 0;
}

li {
  margin-bottom: -0.5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container-fluid s1">
  <div class="container py-5">
    <div class="row py-5 align-items-end">

      <div class="col-sm text-center">
        <img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
        <a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product">
          <div class="circle">
            <h2>Title 1</h2>
            <div class="hidden"><br>
              <ul class="list-unstyled">
                <li class="list-item"><span class="link">Top Picks</span></li>
                <li class="list-item"><span class="link">By Brand</span></li>
                <li class="list-item"><span class="link">By Price</span></li>
              </ul>
            </div>
          </div>
        </a>
      </div>

      <div class="col-sm text-center">
        <img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
        <a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product">
          <div class="circle">
            <h2>Title 1</h2>
            <div class="hidden" id="2"><br>
              <ul class="list-unstyled">
                <li class="list-item"><span class="link">Top Picks</span></li>
                <li class="list-item"><span class="link">By Brand</span></li>
                <li class="list-item"><span class="link">By Price</span></li>
              </ul>
            </div>
          </div>
        </a>
      </div>

      <div class="col-sm text-center">
        <img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
        <a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product">
          <div class="circle">
            <h2>Title 1</h2>
            <div class="hidden"><br>
              <ul class="list-unstyled">
                <li class="list-item"><span class="link">Top Picks</span></li>
                <li class="list-item"><span class="link">By Brand</span></li>
                <li class="list-item"><span class="link">By Price</span></li>
              </ul>
            </div>
          </div>
        </a>
      </div>

    </div>
  </div>
</div>

No necesita ningún ID o clase indexada numéricamente ahora.

0
CertainPerformance 24 abr. 2020 a las 00:54

Deshágase de id y simplemente use la clase .product, luego repita todo

$('.product').each(function(i,v){
    console.log({i:i,v:v,'$(this)':$(this)});
    $(this).on('click',function(){
        $(this).toggleClass('expand');
        $(this).find('.hidden').toggleClass('show');
    })
});

En su html actual, así es como dijo que se ve el producto DOM:

  <div class="col-sm text-center">
    <img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
    <a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product2">
      <div class="circle" id="product1">
        <h2>Title 1</h2>
        <div class="hidden" id="2"><br>
          <ul class="list-unstyled">
            <li class="list-item"><span class="link">Top Picks</span></li>
            <li class="list-item"><span class="link">By Brand</span></li>
            <li class="list-item"><span class="link">By Price</span></li>
          </ul>
        </div>
      </div>
    </a>
  </div>

Al cambiar solo esta línea:

      <div class="circle" id="product1">

Para:

      <div class="circle product">

Puede iterar a través de todos y alternar clases para sí mismo y su hijo '.hidden'

La palabra clave $(this) tiene un significado especial dentro de las funciones de devolución de llamada como .each(), sin embargo, también la dejé en function(i,v), que significa function(index,value) para que incluso pueda usarlas, como lo mostré a través de la consola .


Mostrando solo un círculo de productos a la vez

Lo dejé todo como el simple toggleClass() que compartiste anteriormente, aunque si quieres ser más explícito puedes usar las comprobaciones de hasClass(), y también puedes tener solo un círculo de producto visible en todo momento al agregar esto a primera línea del controlador de clics:

$('.product.expand').removeClass('expand').find('.hidden').removeClass('show');


Fragmento / Fiddle de trabajo

Codeply necesita que cree una cuenta y no incluye código dentro de la publicación en caso de que el servicio se caiga en el futuro, por lo que moví esto dentro de un fragmento de stackoverflow para que pueda ver el código de trabajo.

$('.product').each(function(i,v){
        console.log({i:i,v:v,'$(this)':$(this)});
        $(this).on('click',function(){
            $(this).toggleClass('expand');
            $(this).find('.hidden').toggleClass('show');
        })
    });

    // $('.product1').click(function() {
    //   $(this).nextAll('.hidden:first').toggleClass('show');
    // });
a {
	 font-size: 2.25em;
}
 .active {
	 color: #6bd627;
}
 .circle {
	 width: 150px;
	 height: 150px;
	 background-color: #00aae8;
	 border-radius: 50%;
	 justify-content: center;
	 align-items: center;
	 display: flex;
	 transition: all 0.3s ease-in-out;
	 position: absolute;
}
 .circle h2 {
	 color: #fff;
	 font-size: 0.7em;
	 margin-bottom: auto;
	 margin-top: 55px;
}
 .expand {
	 height: 248px !important;
	 background-color: #6bd627 !important;
	 border-top-left-radius: 50%;
	 border-top-right-radius: 50%;
	 border-bottom-left-radius: 0%;
	 border-bottom-right-radius: 0%;
	 transition: all 0.3s ease-in-out;
	 position: absolute;
}
 .hidden {
	 display: none;
	 opacity: 0;
	 transition: all 0.3s ease-in-out;
}
 .show {
	 display: block !important;
	 position: absolute;
	 opacity: 1;
	 transition: all 0.3s ease-in-out;
}
 .link {
	 font-size: 0.5em;
	 color: #000;
}
 ul, ol {
	 margin: 0;
}
 li {
	 margin-bottom: -0.5em;
}
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

<div class="container-fluid s1" style="margin-bottom:400px;">
    <div class="container py-5">
    <div class="row py-5 align-items-end">
        
      <div class="col-sm text-center">
        <img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
        <a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product1">
          <div class="circle product">
            <h2>Title 1</h2>
            <div class="hidden" id="1"><br>
              <ul class="list-unstyled">
                <li class="list-item"><span class="link">Top Picks</span></li>
          		<li class="list-item"><span class="link">By Brand</span></li>
        		<li class="list-item"><span class="link">By Price</span></li>
              </ul>
            </div>
          </div>
        </a>
      </div>
      
      <div class="col-sm text-center">
        <img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
        <a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product2">
          <div class="circle product">
            <h2>Title 1</h2>
            <div class="hidden" id="2"><br>
              <ul class="list-unstyled">
                <li class="list-item"><span class="link">Top Picks</span></li>
          		<li class="list-item"><span class="link">By Brand</span></li>
        		<li class="list-item"><span class="link">By Price</span></li>
              </ul>
            </div>
          </div>
        </a>
      </div>
      
      <div class="col-sm text-center">
        <img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
        <a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product1">
          <div class="circle product">
            <h2>Title 1</h2>
            <div class="hidden"><br>
              <ul class="list-unstyled">
                <li class="list-item"><span class="link">Top Picks</span></li>
          		<li class="list-item"><span class="link">By Brand</span></li>
        		<li class="list-item"><span class="link">By Price</span></li>
              </ul>
            </div>
          </div>
        </a>
      </div>

    </div>
    </div>
  </div>
0
Daniel Brose 24 abr. 2020 a las 01:09