@Keit265

Как закрыть блок на крестик и запомнить, что он был закрыт?

Нужно, чтобы при нажатии на крестик, блок исчез и к другому блоку/блокам был добавлен нужный класс. К тому же нужно запомнить, что пользователь нажал на крестик и в течение определённого времени не показывать ему объявление снова.
  • Вопрос задан
  • 113 просмотров
Решения вопроса 1
sergiks
@sergiks Куратор тега JavaScript
♬♬
Состояние страницы описывается набором закрытых блоков. Понадобится ещё и время их закрытия, чтобы игнорировать устаревшие. Предлагаю хранить объект, где ключи – id блоков. А значения – timestamp когда их закрыли. Что-то типа
const boxState = {
  "block-ad-123": 1668436835032,
  "block-ad-456": 1668436842279,
};
Хранить этот объект можно в localStorage, переведя в строку: JSON.stringify(boxState)

Изначально закрытых блоков нет, просто пустой объект.

Алгоритм
Загрузили страницу, все блоки видны.
Считали состояние из localStorage, и если там пусто, взяли пустой объект.
Пройти по объекту, и если прошло еще мало времени по очередному ключу, скрыть его блок.
Если времени прошло много – удалить этот ключ из стейта.
Если при обходе объекта были удаления – сохранить обновлённый стейт в localStorage.
spoiler
const boxKey = 'BOX_STATE'; // ключ для хранения в localStorage
const boxState = JSON.parse(localStorage.getItem(boxKey)) ?? {};

const TTL = 36e5; // сколько держать блок скрытым, в миллисекундах (1 час)
const expiredIds = [];
Object.entries(boxState)
  .forEach((key, value) => {
    if (value + TTL < Date.now()) {
      // устарел, более не скрываем
      expiredIds.push(key);
    } else {
      // актуален, скрываем блок
      document.getElementById(key).classList.add("hide");
    }
  });

  if (expiredIds.length) {
    expiredIds.forEach(id => delete boxState[id]);
    localStorage.setItem(boxKey, JSON.stringify(boxState));
  }


При нажатии на крестик:
  1. добавить в стейт id этого блока и текущее время Date.now(),
  2. сохранить состояние в localStorage,
  3. добавить класс блоку.
spoiler
const onClose = ({ target }) => {
  const block = target.closest('div.block');
  const { id } = block;
  boxState[id] = Date.now();
  localStorage.setItem(boxKey, JSON.stringify(boxState));
  block.classList.add("hide");
};
document.querySelectorAll('img.x-button')
  .addEventListener('click', onClose);
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы