Сохранение и чтение из хранилища сессий

496
19 ноября 2017, 17:39

Не могу понять, где и в чём ошибка. Хочу сохранить в сессию страницы нажатые кнопки фильтров, чтобы после перезагрузки страницы и т.п. восстановить выбор пользователя.

  • Каждая кнопка имеет уникальный атрибут id;
  • Кнопка нажата, если есть .btn-warning.

Как организована логика

  • При загрузке страницы получаю из сессионного хранилища id нажатых ранее кнопок;
  • Если такие есть, то добавляю к каждой .btn-warning и перезапускаю фильтрацию;
  • При нажатии на любую кнопку фильтра получаю список всех нажатых кнопок и заношу его в сессионное хранилище (ниже кода этой функции нет, т.к. только будет путь и засорять).

Ниже код

const CHECKED_FILTER_CLASS='btn-warning'; //имя класса, наличие которого у кнопки определяет нажата она или нет / нужно её учитывать или нет
const SESSION_STORAGE_ACTIVE_FILTERS_NAME='active_filters'; //имя ключа в сессионном хранилище js с json массивом нажатых кнопок фильтров

let active_filters=load_from_session(SESSION_STORAGE_ACTIVE_FILTERS_NAME); //Получаем данные из сессии страницы о нажатых кнопках
//Если есть данные, то восстанавливаем кнопки и перезапускаем фильтр.
if ((active_filters && active_filters.length>0){
    restore_pushed_filter_buttons(active_filters);
    //apply_filter();
}
/**
 * Делает указанные кнопки нажатыми
 *
 * @param buttons - массив с id кнопок
 * @returns {boolean}
 */
function restore_pushed_filter_buttons(buttons) {
    for (i = buttons.length - 1; i >= 0; i--) {
        jQuery('#'+buttons[i]).addClass(CHECKED_FILTER_CLASS);
    }
    return true;
}
/**
 * Сохраняет переданные данные в сессию вкладки
 *
 * @param key - имя ключа, под которым данные будут сохранены в сессии
 * @param data - данные, которые будут сохранены в сессии
 * @returns {boolean}
 */
function save_in_session(key, data) {
    if (Array.isArray(data)){
        data=JSON.stringify(data);
    }
    sessionStorage.setItem(key, data);
    return true;
}
/**
 * Получает из сессии вкладки данные по ключу
 *
 * @param key - имя ключа в сесси
 * @return {boolean}
 */
function load_from_session(key) {
    let data=sessionStorage.getItem(key);
    if (data) {
        return JSON.parse(data);
    }
    return false;
}

Проблема следующая - данные в сессии НЕ сохраняются, если перейти на любую другую страницу. НО если закомментировать весь код в функции load_from_session(), то данные сохраняются (если смотреть в инструментах разработчика google chrome -> Application - > Session store) при переходах по сайту.

Я проверяю существование данных в сессии путём их загрузки оттуда с помощью функции load_from_session() каждый раз при инициализации js. Не понятно только, почему данные после считыванию удаляются... Пробовал сразу же после считывания записать эти данные обратно:

function load_from_session(key) {
    let data=sessionStorage.getItem(key);
    save_in_session(SESSION_STORAGE_ACTIVE_FILTERS_NAME, data); //костыль, который не работает.
    if (data) {
        return JSON.parse(data);
    }
    return false;
}

Но ничего всё равно не работает. Чёрт знает что. Если поможет делу, то вот ссылка на девелоп - https://krol.of.by/catalog

Answer 1

У вас ошибка в логике, в функции get_active_filters, которая в вашем вопросе не представлена)

При переходе на любую страницу(не каталог), функция get_active_filters выполняется при загрузке страницы и ищет выбранные фильтры. Поскольку фильтров нету(поскольку на страницы нет фильтрации), то она считает, что не один фильтр не выбран и записывает(вызывает функцию save_in_session) пустое значение с фильтрами в sessionStorage.

Думаю, вам надо как-то определять при загрузке страницы, есть ли вообще блок с фильтрами на странице.

Посмотрите на строчки //---------------------------------------------------------------//

jQuery(document).ready(function(e) { //ОЖИДАНИЕ DOM 
 
 
      // const BUTTON_DATA_FILTER_VALUE_NAME='class'; //имя атрибута data у кнопки фильтров в котором содержится имя-класс текущего фильтра 
      const FILTER_GROUP_MULTIPLE = 'type'; //имя класса тех групп фильтров, которые учитываться должны комплексно. Например ТИП. У каждого кролика может быть несколько типов. И при фильтрации нужно это учитывать 
      const CHECKED_FILTER_CLASS = 'btn-warning'; //имя класса, наличие которого у кнопки определяет нажата она или нет / нужно её учитывать или нет 
      const SESSION_STORAGE_ACTIVE_FILTERS_NAME = 'active_filters'; //имя ключа в сессионном хранилище js с json массивом нажатых кнопок фильтров 
 
 
 
      let active_filters = load_from_session(SESSION_STORAGE_ACTIVE_FILTERS_NAME); //Получаем данные из сессии страницы о нажатых кнопках 
      //Если есть данные, то восстанавливаем кнопки и перезапускаем фильтр. 
      if (active_filters && active_filters.length > 0) { 
        restore_pushed_filter_buttons(active_filters); 
        //**---------------------------------------------------------------**// 
        apply_filter(); // ВЫЗОВ ПРИ ЗАГРУЗКЕ 
      } 
 
      /** 
       * Делает указанные кнопки нажатыми 
       * 
       * @param buttons - массив с id кнопок 
       * @returns {boolean} 
       */ 
      function restore_pushed_filter_buttons(buttons) { 
        for (i = buttons.length - 1; i >= 0; i--) { 
          jQuery('#' + buttons[i]).addClass(CHECKED_FILTER_CLASS); 
        } 
 
        return true; 
      } 
 
      /** 
       * Сохраняет переданные данные в сессию вкладки 
       * 
       * @param key - имя ключа, под которым данные будут сохранены в сессии 
       * @param data - данные, которые будут сохранены в сессии 
       * @returns {boolean} 
       */ 
      function save_in_session(key, data) { 
        if (Array.isArray(data)) { 
          data = JSON.stringify(data); 
        } 
        sessionStorage.setItem(key, data); 
 
        return true; 
      } 
 
      /** 
       * Получает из сессии вкладки данные по ключу 
       * 
       * @param key - имя ключа в сесси 
       * @return {boolean} 
       */ 
      function load_from_session(key) { 
        let data = sessionStorage.getItem(key); 
        // save_in_session(SESSION_STORAGE_ACTIVE_FILTERS_NAME, data); //костыль, который не работает. 
        if (data) { 
          return JSON.parse(data); 
        } 
 
        return false; 
      } 
 
 
 
 
 
      rabbit_resizer(); 
 
 
 
      jQuery('.filter-btn').click(function() { 
        if (is_filter_button_pushed($(this))) { 
          $(this).removeClass(CHECKED_FILTER_CLASS); 
        } else { 
          $(this).addClass(CHECKED_FILTER_CLASS); 
        } 
 
        // console.log(get_active_filters()); 
        // console.log(get_unactive_filters()); 
        // console.log(get_unactive_filters()); 
        apply_filter(); 
      }); 
 
      function apply_filter() { 
        hide_all_rabbits(); 
         //**---------------------------------------------------------------**// 
        show_filters_rabbits(get_active_filters(), get_unactive_filters());// УСТАНОВКА ФИЛЬТРОВ 
      } 
 
 
      function is_filter_button_pushed(ob) { 
        if (ob.hasClass(CHECKED_FILTER_CLASS)) { 
          return true; 
        } 
 
        return false; 
      } 
 
 
 
      function get_active_filters() { 
        let selected_filters = []; 
        jQuery(".filter-btn").each(function() { 
          if ($(this).hasClass(CHECKED_FILTER_CLASS)) { 
            selected_filters.push($(this).attr('id')) 
          } 
        }); 
        //**---------------------------------------------------------------**// 
        save_in_session('active_filters', selected_filters);// ПЕРЕЗАПИСЫВАНИ sessionStorage ФИЛЬТРОВ 
 
        return selected_filters; 
      } 
    }

READ ALSO
Tabs внутри slick slider

Tabs внутри slick slider

Есть вот такой простой скрипт для tabs, по клику разворачивает и сворачивает текстРаботает хорошо, но проблема когда вставляю этот таб в slick slider

358
Как реализовать парсер для инстаграма

Как реализовать парсер для инстаграма

Мне нужно получить информацию о местонахождениях каждого города в определенной стране Пример: у меня есть эта ссылка Локация Эта ссылка...

302
JavaScript, не умножается с дробью?

JavaScript, не умножается с дробью?

Привет, есть простой калькулятор на javascriptОн берет значения из введенных input'ов и умножает

398
Кто имеет авторские права на плагин если написан он усилием сообщества?

Кто имеет авторские права на плагин если написан он усилием сообщества?

Всем приветВчера мне помогли написать плагин на jquery

218