Как сохранить параметры JS при обновлении страницы (скрипт изменения стиля отображения вида карточек товара)
Всем добрый день. Есть простой не замысловатый код:
const listViewButton = document.querySelector('.list-view-button');
const gridViewButton = document.querySelector('.grid-view-button');
const list = document.querySelector('ol');
listViewButton.onclick = function() {
list.classList.remove('grid-view-filter');
list.classList.add('list-view-filter');
}
gridViewButton.onclick = function() {
list.classList.remove('list-view-filter');
list.classList.add('grid-view-filter');
}
body {
font-family: 'Helvetica';
background-color: #0e2439;
}
.filter-buttons {
display: flex;
margin-bottom: 20px;
}
.list-view-button,
.grid-view-button {
color: white;
border: 1px solid white;
padding: 5px;
font-size: 14px;
cursor: pointer;
border-radius: 3px;
}
.list-view-button:hover,
.grid-view-button:hover {
background: white;
color: #0e2439;
}
.list-view-button {
margin-right: 10px;
}
.list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
}
li {
background-color: #1f364d;
color: white;
border-radius: 3px;
margin-bottom: 10px;
transition: 0.3s;
}
.list.list-view-filter {
flex-direction: column;
}
.list.list-view-filter li {
padding: 10px;
}
.list.grid-view-filter {
flex-flow: row wrap;
}
.list.grid-view-filter li {
width: calc(50% - 210px);
padding: 100px;
margin-right: 10px;
text-align: center;
}
<div class="filter-buttons">
<div class="list-view-button"><i class="fa fa-bars" aria-hidden="true"></i> List view</div>
<div class="grid-view-button"><i class="fa fa-th-large" aria-hidden="true"></i> Grid view</div>
</div>
<ol class="list list-view-filter">
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
<li>List item 5</li>
<li>List item 6</li>
</ol>
Я не знаю как добавить JS (не спец в JS) чтобы сохраняло параметры в браузере даже в рамках 1-ой сессии
Ответы (2 шт):
Самое простое - пиши в кастомные куки инфу о включенных опциях, типо кука пусть называется user_view и в ней значение list или grid, при загрузке документа пытайся считать куку, если нет - ставим дефолтный вид, если есть - ставим то что выбрано, но надо учитывать что в сафари еще с прошлого года конкретно так порезали время жизни куки на уровне браузера, в хроме тоже вроде как недавно то же самое сделали, короче вечную куку уже не создашь
Написал пример с использованием cookie и localStorage? в скрипте есть переменная cookieOrLocal, если cookieOrLocal = 'localStorage'. то скрипт будет брать settings из localstorage, соответственно, если cookieOrLocal = 'cookie', то данные будут браться из cookie? это чтобы Вы понялм принцип работы того и другого. В скрипте есть имитация пагинации.
ВНИМАНИЕ! - stackoverflow не разрешает использовать cookie и localStorage, скопируйте код локально и запустите
const buttonsList = document.querySelectorAll('.content-settings-icon')
const buttons = document.querySelectorAll('button')
const list = document.querySelector('.products')
const pagination = document.querySelectorAll('.pagination-element')
let localSettings = ''
let cookieSettings = ''
/** 'cookie' - данные берутся из cookie
** 'localStorage' - данные берутся из localStorage
**/
let cookieOrLocal = 'localStorage' // cookie || localStorage
console.log('Данные берутся из '+cookieOrLocal)
/** функция для получения переменной из cookie по имени */
function getCookie(name) {
let matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
if(cookieOrLocal === 'cookie') {
cookieSettings = JSON.parse(getCookie('settings'))
} else if(cookieOrLocal === 'localStorage') {
localSettings = JSON.parse(localStorage.getItem('settings'))
}
/** стартовые настрйоки */
let settings = {
page: '1',
listStyle: 'grid',
elementsStart: 1,
elementsEnd: 8
}
/** если есть что-то в localStorage, то берем значения оттуда */
if(localSettings) {
settings = localSettings
} else if(cookieSettings) {
settings = cookieSettings
}
/** добавляем класс для списка продуктов */
list.classList.add(settings.listStyle)
/** имитация страниц */
const clickOnPagination = (e) => {
settings.page = e.target.dataset.page
if(settings.page === '1') {
settings.elementsStart = 1
settings.elementsEnd = 8
} else if(settings.page === '2') {
settings.elementsStart = 9
settings.elementsEnd = 16
} else if(settings.page === '3') {
settings.elementsStart = 17
settings.elementsEnd = 24
}
localStorage.setItem('settings', JSON.stringify(settings))
document.cookie = "settings="+JSON.stringify(settings)
}
/** отрисовываем продукты */
for(let i = settings.elementsStart; i <= settings.elementsEnd; i++) {
let element = document.createElement('li')
element.textContent = i
list.appendChild(element)
}
/** нажатие на иконки */
const clickOnButton = (e) => {
if(e.target.classList.contains('active')) return
/** удаляем у всех кнопок класс active */
buttonsList.forEach(btn => {
btn.classList.remove('active')
})
/** удаляем ткущий класс у списка */
list.classList.remove(settings.listStyle)
/** добавить класс active нажатому элементу */
e.target.classList.add('active')
/** обновляем settings */
settings.listStyle = e.target.dataset.list
/** добавляем новый класс списку */
list.classList.add(settings.listStyle)
/** сохраняем settings в localStorage */
localStorage.setItem('settings', JSON.stringify(settings))
/** сохраняем settings в cookie */
document.cookie = "settings="+JSON.stringify(settings)
}
buttonsList.forEach(btn => {
if(btn.dataset.list === settings.listStyle) btn.classList.add('active')
btn.addEventListener('click', clickOnButton)
})
pagination.forEach(item => {
if(item.dataset.page === settings.page) {
item.classList.add('active')
}
item.addEventListener('click', clickOnPagination)
})
body {
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
}
.content-settings {
margin: 20px 0;
text-align: right;
}
.content-settings span {
display: inline-block;
}
.content-settings-icon {
border: 1px solid #ccc;
display: inline-flex;
align-items: center;
justify-content: center;
width: 25px;
height: 25px;
border-radius: 5px;
padding: 3px;
margin: 0 3px;
cursor: pointer;
}
.content-settings-icon:hover {
background-color: #eee;
}
.content-settings-icon.active {
background-color: cornflowerblue;
}
.content-settings-icon svg {
pointer-events: none;
width: 100%;
height: 100%;
}
.content-settings-icon svg path {
fill: #999;
}
.content-settings-icon.active svg path {
fill: #fff;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
.products {
background-color: #eee;
margin-bottom: 20px;
}
.products.list {
display: block;
padding: 5px 0;
}
.products.list li {
margin: 5px 10px 10px;
}
.products.grid {
padding: 10px;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 10px 10px;
grid-template-areas:
". . . ."
". . . .";
}
.products li {
border: 1px solid #ccc;
background-color: #f5f5f5;
flex: 1 1 20%;
padding: 10px 20px;
font-size: 32px;
font-weight: 700;
color: #999;
border-radius: 5px;
}
.pagination {
display: flex;
align-items: center;
justify-content: center;
}
.pagination li a {
border: 1px solid #ccc;
display: inline-block;
padding: 5px 10px;
margin: 0 3px;
text-decoration: none;
color: #999999;
border-radius: 3px;
font-weight: 700;
}
.pagination li a:hover {
background-color: #eee;
}
.pagination li a.active {
background-color: #ddd;
}
button {
background-color: #eee;
border: 1px solid #ccc;
border-radius: 3px;
margin: 0 5px;
padding: 5px 10px;
cursor: pointer;
}
button:hover {
background-color: #e5e5e5;
}
button.active {
background-color: cornflowerblue;
color: #fff;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="content">
<div class="content-settings">
<div class="content-settings-icon" data-list="grid"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M20.25 12.0283C21.2165 12.0283 22 12.8118 22 13.7783V16.2783C22 17.2448 21.2165 18.0283 20.25 18.0283H17.75C16.7835 18.0283 16 17.2448 16 16.2783V13.7783C16 12.8118 16.7835 12.0283 17.75 12.0283H20.25ZM6.25 12.0283C7.2165 12.0283 8 12.8118 8 13.7783V16.2783C8 17.2448 7.2165 18.0283 6.25 18.0283H3.75C2.7835 18.0283 2 17.2448 2 16.2783V13.7783C2 12.8118 2.7835 12.0283 3.75 12.0283H6.25ZM13.25 12.0283C14.2165 12.0283 15 12.8118 15 13.7783V16.2783C15 17.2448 14.2165 18.0283 13.25 18.0283H10.75C9.7835 18.0283 9 17.2448 9 16.2783V13.7783C9 12.8118 9.7835 12.0283 10.75 12.0283H13.25ZM13.25 5.02832C14.2165 5.02832 15 5.81182 15 6.77832V9.27832C15 10.2448 14.2165 11.0283 13.25 11.0283H10.75C9.7835 11.0283 9 10.2448 9 9.27832V6.77832C9 5.81182 9.7835 5.02832 10.75 5.02832H13.25ZM20.25 5.02832C21.2165 5.02832 22 5.81182 22 6.77832V9.27832C22 10.2448 21.2165 11.0283 20.25 11.0283H17.75C16.7835 11.0283 16 10.2448 16 9.27832V6.77832C16 5.81182 16.7835 5.02832 17.75 5.02832H20.25ZM6.25 5.02832C7.2165 5.02832 8 5.81182 8 6.77832V9.27832C8 10.2448 7.2165 11.0283 6.25 11.0283H3.75C2.7835 11.0283 2 10.2448 2 9.27832V6.77832C2 5.86015 2.70711 5.10713 3.60647 5.03412L3.75 5.02832H6.25Z" fill="#212121"/></svg></div>
<div class="content-settings-icon" data-list="list"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.75 2.02002C4.7835 2.02002 4 2.80352 4 3.77002V6.27002C4 7.23652 4.7835 8.02002 5.75 8.02002H18.25C19.2165 8.02002 20 7.23652 20 6.27002V3.77002C20 2.80352 19.2165 2.02002 18.25 2.02002H5.75Z" fill="#212121"/><path d="M5.75 9.02002C4.7835 9.02002 4 9.80352 4 10.77V13.27C4 14.2365 4.7835 15.02 5.75 15.02H18.25C19.2165 15.02 20 14.2365 20 13.27V10.77C20 9.80352 19.2165 9.02002 18.25 9.02002H5.75Z" fill="#212121"/><path d="M5.75 16.02C4.7835 16.02 4 16.8035 4 17.77V20.27C4 21.2365 4.7835 22.02 5.75 22.02H18.25C19.2165 22.02 20 21.2365 20 20.27V17.77C20 16.8035 19.2165 16.02 18.25 16.02H5.75Z" fill="#212121"/></svg></div>
</div>
<ul class="products">
</ul>
</div>
<ul class="pagination">
<li><a href="?page=1" class="pagination-element" data-page="1">1</a></li>
<li><a href="?page=2" class="pagination-element" data-page="2">2</a></li>
<li><a href="?page=3" class="pagination-element" data-page="3">3</a></li>
</ul>
<script src="scripts.js"></script>
</body>
</html>