Preciso de ajuda ! Dúvida ao adicionar mouseover e mouseleave em JavaScript

Bom dia, tenho uma lista de produtos, onde ao passar o mouse por cima do icone mostra um container com os ingredientes da pizza. O problema é que quando clico em uma opção do menu (esse menu filtra as pizzas por categoria), o mouseover não funciona mais. Somente se eu recarregar a página é que o mouseover funciona, mas ao clicar em qualquer item do menu e depois tentar ver o efeito não tem jeito pois parece que o mouseover se perde depois do clique.

Já tentei criar um array para cada categoria de pizza, pois pensava que era por causa do filter mas também não funcionou.

Link do vídeo:

Parte do Código HTML

<section class="section-pizzaria">
        <p>
            Nossas pizzas são de receitas uruguaias que foram adaptadas por nós mesmos. Após assadas,
            as pizzas são servidas em uma pedra de granito mantendo a pizza aquecida para que ela não esfrie.
        </p>
        <h2>Tamanhos:</h2>
        <ul class="pizza-size">
            <li>Grande - 24 pedaços - 3 sabores <a href="#">Ver</a></li>
            <li>Média - 16 pedaços - 2 sabores <a href="#">Ver</a></li>
            <li>Pequena - 10 pedaços - 1 sabor <a href="#">Ver</a></li>
        </ul>
        <h2>Nossos sabores</h2>
        <div class="filter">
            <ul class="ul-filter">
                <li class="all">TODOS</li>
                <li class="meat">CARNE</li>
                <li class="chicken">FRANGO</li>
                <li class="special">ESPECIAL</li>
                <li class="cheese">QUEIJO</li>
                <li class="spicy">PICANTE</li>
                <li class="fish">FRUTOS DO MAR</li>
                <li class="sweet">DOCE</li>
            </ul>
        </div>
        <div class="container-pizza"></div>
    </section>
</body>
<script defer type="text/javascript" src="./scripts.js"></script>
<script type="text/javascript" src="./products.js"></script>
<script type="text/javascript" src="./createListPizza.js"></script>
<script src="https://unpkg.com/swiper@8/swiper-bundle.min.js"></script>

</html>

Código JavaScript com a função que gera a lista baseada em um array de objetos e as funções que filtram conforme clica no menu de filtro

const containerPizza = document.querySelector(".container-pizza");
const ulFilter = document.querySelectorAll(".ul-filter");
const filterAll = document.querySelector(".all");
const filterMeat = document.querySelector(".meat");
const filterChicken = document.querySelector(".chicken");
const filterFish = document.querySelector(".fish");
const filterCheese = document.querySelector(".cheese");
const filterSpicy = document.querySelector(".spicy");
const filterSpecial = document.querySelector(".special");
const filterSweet = document.querySelector(".sweet");

function showAll(arrayPizza) {
  containerPizza.innerHTML =  "";
  arrayPizza.forEach((item) => {
    const divItemPizza = document.createElement("div");
    divItemPizza.classList.add("item-pizza");
    divItemPizza.classList.add("closed");
    containerPizza.appendChild(divItemPizza);
    
    const imagePizza = document.createElement("img");
    imagePizza.src = item.src;
    divItemPizza.appendChild(imagePizza);

    const h5 = document.createElement("h5");
    h5.textContent = item.name;
    divItemPizza.appendChild(h5);

    const linkA = document.createElement("a");
    linkA.classList.add("link-icon");
    divItemPizza.appendChild(linkA);

    const icon = document.createElement("i");
    icon.classList.add("bi-card-list");
    linkA.appendChild(icon);

    const divIngredients = document.createElement("div");
    divIngredients.classList.add("ingredients");
    divItemPizza.appendChild(divIngredients);

    const paragraph = document.createElement("p");
    paragraph.textContent = item.ingredients;
    divIngredients.appendChild(paragraph);
  });
}

function filterStick() {
  const pizzaMeat = savoryPizza.filter((pizza) => {
    return pizza.category == "meat";
  });
  showAll(pizzaMeat);
}

function filterFrango() {
  const pizzaChicken = savoryPizza.filter((pizza) => {
    return pizza.category == "chicken";
  });
  showAll(pizzaChicken);
}

function filterEspecialidades() {
  const pizzaSpecial = savoryPizza.filter((pizza) => {
    return pizza.category == "special";
  });
  showAll(pizzaSpecial);
}

function filterDoces() {
  const pizzaSweet = savoryPizza.filter((pizza) => {
    return pizza.category == "sweet";
  });
  showAll(pizzaSweet);
}

function filterPicantes() {
  const pizzaSpicy = savoryPizza.filter((pizza) => {
    return pizza.category == "spicy";
  });
  showAll(pizzaSpicy);
}

function filterQueijo() {
  const pizzaCheese = savoryPizza.filter((pizza) => {
    return pizza.category == "cheese";
  });
  showAll(pizzaCheese);
}

function filterPeixe() {
   const pizzaFish = savoryPizza.filter((pizza) => {
    return pizza.category == "fish";
  });
  showAll(pizzaFish);
}


document.addEventListener("DOMContentLoaded", showAll(savoryPizza));

filterAll.addEventListener("click", () => showAll(savoryPizza));
filterMeat.addEventListener("click", filterStick);
filterChicken.addEventListener("click", filterFrango);
filterSpecial.addEventListener("click", filterEspecialidades);
filterSweet.addEventListener("click", filterDoces);
filterSpicy.addEventListener("click", filterPicantes);
filterCheese.addEventListener("click", filterQueijo);
filterFish.addEventListener("click", filterPeixe);

Código JavaScript

const linkIcon = document.querySelectorAll(".link-icon");

linkIcon.forEach((link) => {
  link.addEventListener("mouseover", function () {
    const item = this.parentNode; // parentNode é o pai do nó la do HTML (classe item)
    const isActive = item.classList.contains("active");

    if (!isActive) {
      item.classList.remove("closed");
      item.classList.add("active");
    }
  });
});

linkIcon.forEach((link) => {
  link.addEventListener("mouseleave", function () {
    const item = this.parentNode; // parentNode é o pai do nó la do HTML (classe item)
    const isActive = item.classList.contains("active");

    if (isActive) {
      item.classList.remove("active");
      item.classList.add("closed");
    }
  });
});

CSS de alguns elementos

.container-pizza {
    display: grid;
    grid-template-columns: 350px 350px 350px 350px;
    gap: 20px;
}

.item-pizza {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 20px;
    position: relative;
}

.item-pizza img {
    width: 350px;
}

.item-pizza h5, .item-pizza i {
    font-size: 25px;
    color: #222222;
}

.item-pizza a {
    cursor: pointer;
}

.item-pizza i {
    font-size: 35px;
}

.item-pizza i:hover  {
    color: #4387F7;
}

.ingredients {
    background-color: #ff5252;
    position: absolute;
    top: 70px;
    border-radius: 10px;
    transition: 1s;
}

.item-pizza p {
    width: 100%;
    color: #FDFDFD;
    margin: 0 auto;
    font-weight: 500;
}
.closed .ingredients {
    overflow: hidden;
    max-height: 0;
}

.active .ingredients {
    max-height: 350px;
}

.ul-filter {
    display: flex;
    gap: 80px;
    list-style-type: none;
    margin-top: 40px;
    margin-bottom: 40px;
    border-bottom: solid 2px #262626;
    padding: .5rem;
}

.ul-filter li {
    cursor: pointer;
    font-weight: 500;
    border: none;
}

.ul-filter li:hover {
    color: #4387F7;
}

Aparentemente, o problema é que vc inicializa os elementos .link-icon apenas uma vez, mas cada vez que as pizzas são filtradas, vc cria novos elementos, que não terão os eventos de mouseover e mouseleave registrados. Uma “solução” rápida é procurar novamente pelos elementos (document.querySelectorAll(".link-icon")) e registrar os eventos (já que agora serão outros elementos, pois estes foram criados de novo).

Outra solução é criar os elementos apenas uma vez e deixá-los ocultos, e quando ocorrer um mouseover vc faz com que ele fique visível (por exemplo, apenas mudando a classe dele de active para closed).

2 curtidas

Muito obrigado, agora funcionou, abraço !