Tengo dos divs creados a partir del bucle PHP:
<div class="sku"> <span class="sku-value" data-id="150">1000</span> <span class="sku-value" data-id="151">2000</span> <span class="sku-value" data-id="152">3000</span> </div> <div class="size-values"> <span class="size-value" data-id="150">M</span> <span class="size-value" data-id="151">L</span> <span class="size-value" data-id="152">XL</span> </div> Estos divs tienen un div padre llamado atributos.
sku-value y size-value tienen algo en común: el atributo data-id.
Con CSS, estoy manipulando los sku-value :
.sku-value { display:none; } .sku-value.active { display:inline-block; }Con jQuery, solo muestro el primer valor de tamaño:
$('.sku-value:first').addClass('active');Entonces, en este caso, cuando se carga la página, solo se verá este valor sku:
<span class="sku-value" data-id="150">1000</span>Con mi código a continuación, puedo cambiar con éxito la clase activa de cada valor de tamaño en el que se hizo clic, pero ¿cómo puedo cambiar el valor de sku que se muestra que coincide con el valor de identificación de datos?
Por ejemplo: si un usuario hace clic en uno de valor de tamaño que tiene id. de datos 152, ¿cómo puedo mostrar el sku-value que tiene id. de datos 152 y ocultar el sku-value visible actual?
$(document).ready(function(){ $('.sku-value:first').addClass('active'); $('.attributes').find('.size-value').on('click', function(){ if ($this.hasClass('active')) { $this.removeClass('active'); } else { $this.closest('.size-values').find('.size-value').removeClass('active'); $this.addClass('active'); } }); });Para lograr lo que necesita, puede recuperar la data-id del elemento en el que se hizo clic, luego use filter() para recuperar todos los elementos por ese atributo de data antes de establecer la clase active en ellos.
Aquí hay un ejemplo que muestra cómo hacerlo, y también algunos ajustes a la lógica para que sea más breve:
$(document).ready(function() { let $skuAttributes = $('.sku-value'); let $sizeAttributes = $('.size-value'); let $allAttributes = $skuAttributes.add($sizeAttributes); // set default state on page load $skuAttributes.first().addClass('active'); $sizeAttributes.first().addClass('active'); // on click of a size attribute, set active class on all relevant elements $sizeAttributes.on('click', function() { $sizeAttributes.removeClass('active'); let dataId = $(this).data('id'); $allAttributes.removeClass('active').filter((i, el) => el.dataset.id == dataId).addClass('active'); }); }); div { font-size: 1.3em; } .sku-value { display: none; } .sku-value.active { display: inline-block; } .active { color: #C00; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="attributes"> <div class="sku"> <span class="sku-value" data-id="150">1000</span> <span class="sku-value" data-id="151">2000</span> <span class="sku-value" data-id="152">3000</span> </div> <div class="size-values"> <span class="size-value" data-id="150">M</span> <span class="size-value" data-id="151">L</span> <span class="size-value" data-id="152">XL</span> </div> </div>Aquí hay una solución de estilo funcional con sabor a vainilla que se me ocurrió. Varias funciones de ayuda comparten el trabajo pesado, por lo que la función de escucha principal se mantiene simple y limpia.
En lugar de la clase active , utiliza una clase hidden que se puede aplicar tanto a sku de SKU como a intervalos de size .
(Llegué tarde a la fiesta porque escribí este guión mientras estaba desconectado hoy).
const // Collects DOM elements as arrays sizes = [...document.getElementsByClassName("size-value")], skus = [...document.getElementsByClassName("sku-value")], spans = [...sizes, ...skus], // Defines helper functions isHidden = (_this) => _this.classList.contains("hidden"), isActive = (_this) => sizes.every((size) => isHidden(size) || size === _this), showAll = (_these) => _these.forEach((_this) => _this.classList.remove("hidden")), hideAll = (_these) => _these.forEach((_this) => _this.classList.add("hidden")), filterByDataId = (_these, id) => _these.filter(_this => _this.dataset.id === id); // Invokes listener when user clicks a size sizes.forEach(size => size.addEventListener("click", hideAndShow)); // Defines listener function hideAndShow({target}){ // Destructures click event if(isActive(target)){ showAll(spans); } else{ hideAll(spans); showAll(filterByDataId(spans, target.dataset.id)); } } div { margin: 1em 0; } span { padding: 0.1em 0.3em; border: 1px solid grey; } .hidden{ display: none; } <div class="sku"> <span class="sku-value" data-id="150">1000</span> <span class="sku-value hidden" data-id="151">2000</span> <span class="sku-value hidden" data-id="152">3000</span> </div> <div class="size-values"> <span class="size-value" data-id="150">Medium</span> <span class="size-value" data-id="151">Large</span> <span class="size-value" data-id="152">Xtra Large</span> </div>