Статьи

Совет: Сохраняйте флажок Проверено состояние после перезагрузки страницы

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

Может быть полезно сохранить постоянный флажок «Проверено состояние», если, например, вы используете флажки, чтобы позволить вашим пользователям устанавливать специфичные для сайта предпочтения, такие как открытие внешних ссылок в новом окне или скрытие определенных элементов страницы.

Для нетерпеливых среди вас есть демонстрация техники в конце статьи.

Разметка флажка

Итак, первое, что нам нужно, это несколько флажков. Вот некоторые, которые я сделал ранее:

<div id="checkbox-container"> <div> <label for="option1">Option 1</label> <input type="checkbox" id="option1"> </div> <div> <label for="option2">Option 2</label> <input type="checkbox" id="option2"> </div> <div> <label for="option3">Option 3</label> <input type="checkbox" id="option3"> </div> <button>Check All</button> </div> 

Вы заметите, что я включил кнопку « Проверить все» , чтобы пользователь мог выбрать или отменить выбор всех полей одним щелчком мыши. Мы вернемся к этому позже.

Надеюсь, вы также заметите, что я использую метки для текста, относящегося к каждому из блоков. Само собой разумеется, что поля формы в любом случае должны иметь метки , но в случае флажков это особенно важно, поскольку позволяет пользователям выбирать / снимать флажок, щелкая текст метки.

Наконец, вы увидите, что я группирую метки и флажки внутри элементов уровня блока (в данном случае элементов <div> ), чтобы они отображались друг под другом и их было проще стилизовать.

Отвечая на изменения

Теперь давайте свяжем обработчик событий с флажками, чтобы что-то происходило всякий раз, когда вы нажимаете на них. Я использую jQuery для этого урока, хотя, конечно, это не обязательно. Вы можете включить его через CDN таким образом:

 <script src="https://code.jquery.com/jquery-2.2.3.min.js"></script> 

Теперь JavaScript:

 $("#checkbox-container :checkbox").on("change", function(){ alert("The checkbox with the ID '" + this.id + "' changed"); }); 

Здесь я использую селектор флажка jQuery psuedo-class : checkbox , которому предшествует идентификатор содержащего элемента <div> ( checkbox-container ). Это позволяет мне настраивать таргетинг только на те флажки, которые меня интересуют, а не на все флажки на странице.

Постоянный флажок Проверено состояние

Как вы, наверное, знаете, HTTP — это протокол без сохранения состояния . Это означает, что он обрабатывает каждый запрос как независимую транзакцию, не связанную с каким-либо предыдущим запросом. Следовательно, если вы установите флажок, а затем обновите страницу, браузер не сможет запомнить предыдущее состояние флажка и — в примере выше — отобразит его в неконтролируемой форме (хотя некоторые браузеры кэшируют значение ).

Чтобы обойти это, мы собираемся хранить состояния флажков на компьютере пользователя, используя локальное хранилище (которое является частью API веб-хранилища ). У него довольно хорошая поддержка браузера:

Чтобы изменить объект localStorage в JavaScript, вы можете использовать методы setItem и getItem :

 localStorage.setItem("favoriteVillan", "Dr. Hannibal Lecter"); console.log(localStorage.getItem("favoriteVillan")); => Dr. Hannibal Lecter 

Чтобы удалить элемент из локального хранилища, используйте метод removeItem .

 localStorage.removeItem("favoriteVillan"); console.log(localStorage.getItem("favoriteVillan")); => null 

Вы можете узнать больше о локальном хранилище здесь: HTML5 Web Storage

Что касается нашего кода, кажется, что, поскольку мы хотим сохранить все флажки, логичным выбором будет создание пар ключ / значение, состоящих из идентификаторов флажков и их соответствующего проверенного состояния. Мы можем сохранить их в объектном литерале, который мы можем добавить в локальное хранилище. Тем не менее, поскольку локальное хранилище может обрабатывать только пары ключ / значение, нам нужно будет структурировать объект перед его сохранением и проанализировать его при извлечении.

Давайте посмотрим, как мы можем это сделать:

 var checkboxValues = JSON.parse(localStorage.getItem('checkboxValues')) || {}; var $checkboxes = $("#checkbox-container :checkbox"); $checkboxes.on("change", function(){ $checkboxes.each(function(){ checkboxValues[this.id] = this.checked; }); localStorage.setItem("checkboxValues", JSON.stringify(checkboxValues)); }); 

Обратите внимание на логический оператор ИЛИ ( || ), который возвращает значение своего второго операнда, если первый является ложным. Мы используем это для назначения пустого объекта переменной checkboxValues , если в локальном хранилище не найдено ни одной записи. Это фактически то же самое, что и написание:

 var checkboxValues = JSON.parse(localStorage.getItem('checkboxValues'); if (checkboxValues === null){ checkboxValues = {}; } 

Также обратите внимание, что мы кэшируем ссылку на флажки, чтобы нам не приходилось продолжать запрашивать DOM. Это небольшой пример в таком маленьком примере, но это хорошая привычка, по мере роста вашего кода.

Последнее, что нужно сделать, это перебрать переменную checkboxValues при загрузке страницы и соответственно установить значение полей:

 $.each(checkboxValues, function(key, value) { $("#" + key).prop('checked', value); }); 

Вот и все. Теперь у нас есть постоянные флажки.

Если вы попытаетесь обновить Code Pen (нажав кнопку RERUN ), вы увидите, что флажки остаются установленными, в то время как если вы введете что-то в текстовый ввод, это исчезнет при перезагрузке.

Проверка и снятие отметки со всех ящиков

Чтобы завершить это, давайте реализуем кнопку « Проверить все» , чтобы пользователи могли выбрать или отменить выбор всего за один раз.

При нажатии эта кнопка должна проверять все флажки. Когда все флажки установлены, его текст должен измениться на Uncheck All, и его состояние также должно храниться в локальном хранилище.

Давайте начнем так:

 var $button = $("#checkbox-container button"); function allChecked(){ return $checkboxes.length === $checkboxes.filter(":checked").length; } function updateButtonStatus(){ $button.text(allChecked()? "Uncheck all" : "Check all"); } $checkboxes.on("change", function(){ ... updateButtonStatus(); }); 

Это приведет к тому, что текст кнопки изменится, когда все флажки будут отмечены или не отмечены.

Единственное, что может быть немного необычным, — это использование троичного условного updateButtonStatus методе updateButtonStatus . Это сокращение для оператора if и эквивалентно:

 if(allChecked()){ $button.text("Uncheck all"); } else { $button.text("Check all"); } 

Теперь функция для выбора и отмены выбора:

 function handleButtonClick(){ $checkboxes.prop("checked", allChecked()? false : true) } $("button").on("click", function() { handleButtonClick(); }); 

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

 var formValues = JSON.parse(localStorage.getItem('checkboxValues')) || {}; function updateStorage(){ $checkboxes.each(function(){ formValues[this.id] = this.checked; }); formValues["buttonText"] = $button.text(); localStorage.setItem("formValues", JSON.stringify(formValues)); } 

И при загрузке страницы:

 $button.text(formValues["buttonText"]); 

демонстрация

Вот что у нас получилось.

Вывод

В этом уроке я продемонстрировал, как сохранить значения формы в локальном хранилище и как реализовать функциональность Check / Uncheck All для флажков в простой форме.

Если у вас есть какие-либо вопросы или комментарии, я был бы рад услышать их ниже.