Attribuer des classes à l'élément cliqué le plus récemment
P粉021854777
P粉021854777 2024-04-03 16:36:09
0
1
503

J'ai un calendrier qui ressemble à ceci, stylisé en utilisant Tailwind CSS :

8 Mercredi est actuellement cliqué, il a donc un fond rose et une ombre rose. Le 7ème est l'élément précédemment cliqué, c'est pourquoi il n'a qu'une ombre rose (j'ai supprimé la classe de fond rose mais j'ai gardé l'ombre rose).

Ce que je veux, c'est conserver le dernier élément précédemment cliqué afin de pouvoir ajouter une ombre rose, mais uniquement au dernier élément et non à tous les éléments précédemment cliqués.

Voici à quoi ressemble mon code JavaScript :

//select needed elements from HTML
const calendarDates = document.querySelectorAll('.clickable')
const dateDisplay = document.getElementById('show-details');
const selectedDateDayElement = document.getElementById('selected-date-day');
const selectedDateElement = document.getElementById('selected-date');

let latestClicked = null;
let latestPreviouslyClicked = null;

// if there is no date, dont add hover efects
for (let i = 0; i < calendarDates.length; i++) {
    if (calendarDates[i].textContent.trim() === '') {
        calendarDates[i].classList.remove('hover:bg-pink-500', 'hover:shadow-md', 'hover:cursor-pointer', 'hover:shadow-pink-500');
        calendarDates[i].classList.add('empty')
    }
}

// select only elements that are not empty
const clickableDates = document.querySelectorAll('.clickable:not(.empty)');


clickableDates.forEach(dateElement => {
    dateElement.addEventListener('click', () => {
        const dateValue = dateElement.textContent.trim();
        const year = 2017;
        const month = 1;

        if (latestClicked !== null) {
            latestPreviouslyClicked = latestClicked;
            latestClicked = null;
            latestPreviouslyClicked.classList.remove('bg-pink-500');
        }

        dateElement.classList.add('bg-pink-500', 'shadow-md', 'shadow-pink-500');
        latestClicked = dateElement;

        const selectedDate = new Date(year, month, parseInt(dateValue));

        const daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
        const dayOfWeek = daysOfWeek[selectedDate.getDay()];

        selectedDateDayElement.textContent = dayOfWeek;
        selectedDateElement.textContent = dateValue;

        dateDisplay.style.display = 'block';
    });
});



// Close the date details when clicked outside, and this works at it should
document.addEventListener('click', event => {
    if (!event.target.classList.contains('clickable')) {
        clickableDates.forEach(element => {
            element.classList.remove('bg-pink-500');
        });
        dateDisplay.style.display = 'none';
    }
});

Le problème auquel je suis confronté est qu'il conserve l'ombre de tous les éléments précédemment cliqués :

Le comportement attendu est :

  • Je clique sur la date A - elle apparaîtra avec un fond et une ombre roses ("bg-pink-500 Shadow-md Shadow-pink-500")
  • Je clique sur la date B - elle apparaît avec un fond et une ombre roses, la date A n'a qu'une ombre
  • Je clique sur la date C - elle obtient un fond et une ombre roses, la date B n'a qu'une ombre, la date A n'a pas de classes supplémentaires ajoutées.

P粉021854777
P粉021854777

répondre à tous(1)
P粉237689596

D'accord, j'ai aussi mal lu votre question.

Le problème réside dans la pièce

if (latestClicked !== null) {
            latestPreviouslyClicked = latestClicked;
            latestClicked = null;
            latestPreviouslyClicked.classList.remove('bg-pink-500');
        }

En fait, vous supprimez simplement l'arrière-plan de l'élément latestClicked, jamais le style d'ombre.

Cela devrait fonctionner :

if(latestPreviouslyClicked !== null) {
  latestPreviouslyClicked.classList.remove('shadow-md', 'shadow-pink-500');
}
// update second latest element after changing the classes
latestPreviouslyClicked = latestClicked;
if(latestClicked !== null) {
  latestClicked.classList.remove('bg-pink-500');
}
latestClicked = dateElement;

La partie importante est de muter l'élément avant de le réaffecter à l'élément suivant.

Ou si lien facultatif fonctionne dans votre environnement (bundle ou ne prend en charge que les nouveaux navigateurs) :

latestPreviouslyClicked?.classList.remove('shadow-md', 'shadow-pink-500');
// update second latest element after changing the classes
latestPreviouslyClicked = latestClicked;

latestClicked?.classList.remove('bg-pink-500');
latestClicked = dateElement;
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal