Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как убрать класс у элемента через 1 секунду (https://javascript.ru/forum/misc/85915-kak-ubrat-klass-u-ehlementa-cherez-1-sekundu.html)

Leon2110 21.05.2024 15:49

Как убрать класс у элемента через 1 секунду
 
Всем привет, есть меню, при наведении на первый уровень, добавляется класс и показывается 2й уровень, когда убираю мышь класс пропадает и второй уровень закрывается, все верно.

Нужно, когда юзер убрал мышь, подождать примерно 1 секунду и если юзер не вернул курсор тогда закрыть второй уровень. Это что-то типа защиты, если резко дернуть мышкой, чтобы второй уровень сразу не закрывался. Вот мой код:

let level1 = document.querySelector('.is-nested');

level1.addEventListener('mouseover', event => {
	level1.classList.add('is-active');
});

level1.addEventListener('mouseout', event => {
	level1.classList.remove('is-active')
});


Вторая часть с mouseout, должна сработать не сразу, а через 1 секунду и если юзер вернул курсор обратно на mouseover, то отмена второй части, ее не нужно выполнять.

Ааа еще заметил, что у меня есть много пунктов меню содержащих второй уровень, а работает только с первым(( Берет .is-nested только у первого пункта меню, можно ли чтобы с другими тоже работало?((


//UPD
Немного получилось, вот какой сейчас код, все вторые уровни работают, все норм, осталось как-то решить вопрос с одной секундой задержки перед закрытием, это не знаю как делать((

// Получаем все элементы с классом .item
	const level1 = document.querySelectorAll('.is-nested');

	// Добавляем обработчик события для каждого элемента
	level1.forEach(item => {
		// Добавляем класс .is-active при наведении мыши
		item.addEventListener('mouseover', () => {
			item.classList.add('is-active');
		});

		// Удаляем класс .acis-active при уходе мыши
		item.addEventListener('mouseout', () => {
			item.classList.remove('is-active');
		});
	});


Даже наверное неверно написал, вот такая логика нужна:
1. Юзер наводит мышь на первый пункт меню содержащий второй уровень, добавляется класс is-active второй уровень отображается.
2. Юзер наводит мышь на второй пункт меню содержащий второй уровень, у первого пункта меню класс .is-active исчезает сразу, у второго пункта меню он появляется сразу и видим на экране второй уровень второго пункта меню.
3. Юзер уводит мышь с меню, через 1 секунду класс .is-active пропадает и все вторые уровни если были открыты закрываются.
4. Юзер уводишь мышь с меню, менее чем на 1 секунду и возвращает курсор обратно, класс .is-active не пропадает, меню не закрывается.

Aetae 21.05.2024 19:42

// Получаем все элементы с классом .item
const level1 = document.querySelectorAll('.is-nested');

// Добавляем обработчик события для каждого элемента
level1.forEach(item => {
  let closeTimer;

  // Добавляем класс .is-active при наведении мыши
  item.addEventListener('mouseenter', () => {
    clearTimeout(closeTimer);
    
    item.classList.add('is-active');
  });

  // Удаляем класс .acis-active при уходе мыши
  item.addEventListener('mouseleave', () => {
    closeTimer = setTimeout(() => {
      item.classList.remove('is-active');
    }, 1 * 1000);
  });
});

Leon2110 21.05.2024 20:32

Спасибо, все шикарно, только не учитывается этот пункт:

2. Юзер наводит мышь на второй пункт меню содержащий второй уровень, у первого пункта меню класс .is-active исчезает сразу, у второго пункта меню он появляется сразу и видим на экране второй уровень второго пункта меню.

Получается я навожу мышь быстро на пункт 1, 2, 3 и они все поверх друг друга появляются и так же через секунду по одному исчезают. А нужно чтобы когда навожу на другой пункт, первый закрывался сразу и второй открывался сразу, без задержек.

Aetae 21.05.2024 21:14

Как-то так, уже мутновато на глазок делать, то тестить лень.:)
// Получаем все элементы с классом .item
const level1 = document.querySelectorAll('.is-nested');
let lastItem;

// Добавляем обработчик события для каждого элемента
level1.forEach(item => {
  let closeTimer;

  // Добавляем класс .is-active при наведении мыши
  item.addEventListener('mouseenter', () => {
    clearTimeout(closeTimer);

    if (lastItem && lastItem !== item) {
      lastItem.classList.remove('is-active');
    } else {
      item.classList.add('is-active');      
    }

    lastItem = item;
  });

  // Удаляем класс .acis-active при уходе мыши
  item.addEventListener('mouseleave', () => {
    closeTimer = setTimeout(() => {
      item.classList.remove('is-active');
    }, 1 * 1000);
  });
});


Часовой пояс GMT +3, время: 05:31.