Сохранить значения формы в localStorage

Я некоторое время изучал JS, поэтому в какой-то момент не смог выполнить задание, которое дал мне мой учитель, поэтому все дело в том, чтобы создать ввод для заполнения тремя селекторами, чтобы изменить некоторые свойства текста.

Что я пытаюсь сделать, так это:
всякий раз, когда пользователь закрывает страницу и открывает ее снова - примените значения из localStorage обратно в форму и примените стили к элементу. То есть:

Font: Roboto
Color: Green
fontSize: 24px

Как я должен это сделать и почему мой код неверен?
Вот код:

function iterator() {
  for (let i = 16; i <= 30; i++) {
    let fontsSize = document.getElementById("fontsSize");
    let CreateElmt = document.createElement("option");
    fontsSize.append(CreateElmt);
    CreateElmt.textContent = i + "px";
    CreateElmt.value = i + "px";
  }
}
iterator();

function finalItreator() {
  let parent = document.querySelector(".daddyDiv");
  let div = document.querySelector(".paragragh");
  let Fonts = document.getElementById("Fonts");
  let Colors = document.getElementById("Colors");
  let fontSizes = document.getElementById("fontsSize");
  parent.addEventListener("input", (e) => {
    window.localStorage.setItem("Font", Fonts.value);
    window.localStorage.setItem("Color", Colors.value);
    window.localStorage.setItem("FontSize", fontSizes.value);
    div.style.fontFamily = Fonts.value;
    div.style.color = Colors.value;
    div.style.fontSize = fontSizes.value;
    for (i = 0; i < Fonts.children.length; i++) {
      if (Fonts.children[i].value === window.localStorage.getItem("Font")) {
        Fonts.forEach((e) => {
          e.removeAttribute("selected");
        });
        Fonts.children[i].classList.add("active");
      }
      if (Fonts.children[i].classList.contains("active")) {
        Fonts.children[i].setAttribute("selected", "");
      }
    }
  });
}
finalItreator();
.paragragh {
  margin: 10px auto;
  width: 400px;
  min-height: 300px;
  background-color: #ddd;
  text-align: center;
  padding-top: 30px;
}
<form class = "daddyDiv">
  <select name = "Fonts" id = "Fonts">
    <option value = "Open Sans">Open Sans</option>
    <option value = "Cairo">Cairo</option>
    <option value = "Roboto">Roboto</option>
  </select>
  <select name = "Colors" id = "Colors">
    <option value = "Black">Black</option>
    <option value = "Green">Green</option>
    <option value = "Blue">Blue</option>
    <option value = "Red">Red</option>
    <option value = "Purple">Purple</option>
  </select>
  <select name = "fontsSize" id = "fontsSize"></select>
  <div class = "paragragh" contenteditable = "true"></div>
</form>

Вам нужно будет создать функцию, которая извлекает эти данные из localStorage, а затем назначать их каждому выбору с помощью document.getElementById("select").selectedIndex = index. Вам понадобится массив всех возможных входных данных для каждого выбора, чтобы сопоставить его индекс со значением select.

Κωνσταντινος Χαφης 07.05.2022 12:31

@ ΚωνσταντινοςΧαφης я не понял, можете ли вы объяснить это ясно?

MrKing09 07.05.2022 12:43

PS: finalItreator лучше бы как finalIterator

Roko C. Buljan 07.05.2022 13:07

@MrKing09 MrKing09, если вы читали DOCS о местное хранилище ... то почти не нужно ничего объяснять: developer.mozilla.org/en-US/docs/Web/API/Window/localStorage Здесь также есть много ответов на SO, которые объясняют, как его использовать.

Roko C. Buljan 07.05.2022 13:12

Определение функции и вызов ее только один раз кажется бессмысленным.

The Fool 07.05.2022 13:51
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
5
88
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  • Нет необходимости снова и снова запрашивать DOM внутри цикла for для одного и того же элемента. Кэшировать элементы, который вы планируете повторно использовать заранее.
  • Используйте const, когда значение переменной не изменится в течение жизни вашего приложения.
  • Что значит "параграф" ты имеешь в виду параграф? (Кстати, это ДЕЛ)
  • Нет необходимости использовать id, если вы уже используете name
  • Не называйте функцию iterator, если ее задача явно состоит в том, чтобы заполнить поле «Выбор» <option>s. createFontSizeOptions кажется лучшим выбором.
  • Не называйте функцию finalItreator, это ничего не значит.
    Описывайте имена функций как можно лаконичнее, осмысленнее и короче.
  • (На самом деле вам эти функции вообще не нужны)
  • Не называйте PascalCase вашего идентификатора. Используйте верблюжий регистр.
  • Назначьте событие "input" селектору класса, то есть: .command, который назначен вашим элементам Select (или другим введенным элементам).
  • Используйте правильный name, значение которого точно соответствует ожидаемому свойству CSS как camelCase, то есть: fontFamily или fontSize
  • Сохраните в LocalStorage литерал строкового объекта, используя JSON.stringify
  • Получить из localStorage, используя JSON.parse
  • Создайте три функции, одну из которых получает строку как объект из localStorage, вторую — для сохранения объекта в localStorage, а третью — для применения стилей пар ключ/значение к нужному элементу с помощью Объект.назначить.
  • Создайте несколько многоразовых утилит DOM, которые помогут вам получать или создавать элементы в DOM.

(Поскольку фрагменты переполнения стека по соображениям безопасности не принимают доступ к localStorage из Iframe, вот живая демонстрация jsFiddle)

Код:

// DOM utility functions:

const el = (sel, par) => (par || document).querySelector(sel);
const els = (sel, par) => (par || document).querySelectorAll(sel);
const elNew = (tag, prop) => Object.assign(document.createElement(tag), prop);


// TASK:

// Cache DOM Elements:
const elForm = el("#formSettings"); // It's not a ".daddyDiv"... it's a Form!
const elEditable = el("#editable"); // It's an editable div! (What means "paragragh" anyways?!)
const elsCommand = els(".command"); // All your input/selects
const elFontSize = el("[name=fontSize]");

// Create the font-size Options
// (You don't need a function here if it's a one-time operation on DOM ready)
for (let i = 16; i <= 30; i++) {
  elFontSize.append(elNew("option", {
    textContent: `${i}px`,
    value: `${i}px`
  }));
}

const commandsGet = () => {
  // If we have no commands stored in localStorage, save them!
  if (!localStorage.commands) commandsSave();
  // Convert string from localStorage to Object Literal
  const commands = JSON.parse(localStorage.commands);
  // Apply values to DOM input/select elements by name
  Object.entries(commands).forEach(([name, value]) => {
    el(`[name = "${name}"]`).value = value;
  });
};

const commandsSave = () => {
  // Create an Object of the commands to save to localStorage
  const commands = [...elsCommand].reduce((obj, elem) => {
    obj[elem.name] = elem.value;
    return obj;
  }, {});
  // Convert object Literal to String and save to localStorage
  localStorage.commands = JSON.stringify(commands);
};

const commandsApply = () => {
  // Apply styles to the desired contenteditable element:
  Object.assign(elEditable.style, JSON.parse(localStorage.commands));
};

// Assign an event listener to all your inputs/selects to store and apply the 
// styles (commands) on "input"
elsCommand.forEach(elem => {
  elem.addEventListener("input", () => {
    commandsSave();
    commandsApply();
  });
});

// Init:
// On page load read the commands from LocalStorage
// and apply them to your editable element
commandsGet();
commandsApply();
/*QuickReset */

* {
  margin: 0;
  box-sizing: border-box;
}

.paragragh {
  margin: 10px auto;
  min-width: 400px;
  min-height: 300px;
  background-color: #ddd;
  text-align: center;
  padding-top: 30px;
}
<form id = "formSettings">
  <select class = "command" name = "fontFamily">
    <option value = "Arial">Arial</option>
    <option value = "Times New Roman">Times New Roman</option>
    <option value = "Courier New">Courier New</option>
  </select>
  <select class = "command" name = "color">
    <option value = "black">Black</option>
    <option value = "green">Green</option>
    <option value = "blue">Blue</option>
    <option value = "red">Red</option>
    <option value = "purple">Purple</option>
  </select>
  <select class = "command" name = "fontSize"></select>

  <div id = "editable" contenteditable = "true">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
</form>

Другие вопросы по теме

Как лучше всего получить целевую подстроку через регулярное выражение в сценарии bash
Как вводить уникальные буквы только в текстовом поле ввода в html или реагировать?
Как сделать обертку div без display: inline-block;?
Нарисуйте два или более изображений вертикально на одном холсте
JQuery для отображения другого текстового поля, отображаемого при выборе двух разных элементов в поле выбора
Как раскрасить навигационную панель шириной 100%, находясь внутри контейнера начальной загрузки
Почему моя рамка диапазона меняет форму в мобильном представлении
Измените значения множественного выбора начальной загрузки на основе других параметров выбора, используя jquery
Как избежать переполнения изображения загрузочной карты в теле карты?
Динамически получать значение определенного элемента из списка элементов с одинаковым идентификатором