I have been studying JS for a while so at some point a couldn’t complete the assignment that my teacher gave me so its all about to create a input to fill with 3 selectors to change some properties of the text.
What I’m trying to do is:
whenever the user he closes the page and opens it again – apply the values from localStorage back into the form, and apply the styles to an element. I.e:
Font: Roboto
Color: Green
fontSize: 24px
How I am supposed to do it, and why my code is wrong?
Here’s the code :
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>
Advertisement
Answer
- There’s no need to query the DOM inside a for loop for the same element again and again.
Cache the elements you plan to reuse beforehand. - Use
const
when the variable value will not change through the life of your app - What means “paragragh” you mean paragraph? (BTW, it’s a DIV)
- There’s no need to use
id
if you already usename
- Don’t name a function
iterator
if its job is clearly to populate a Select box with<option>
s.createFontSizeOptions
seems like a better choice. - Don’t name a function
finalItreator
it means nothing.
Describe your function names as concisely, meaningfully, and short as possible. - (Actually, you don’t need those functions at all)
- Don’t name your ID’s PascalCase. Use camelCase.
- Assign the
"input"
Event to a class selector, i.e:.command
which is assigned to your Select (or other imput) elements. - Use a proper
name
which value is exactly the expected CSS property as camelCase, i.e:fontFamily
orfontSize
- Store into LocalStorage a Stringified Object literal using JSON.stringify
- Retrieve from localStorage using JSON.parse
- Create three functions, one that gets the String as Object from localStorage, the second to save an Object to localStorage, and a third one to apply the key/value pairs styles to a desired element using Object.assign
- Create some reusable DOM utilities to help you with getting or creating elements in the DOM
(Since Stack Overflow Snippets for security reasons doesn’t accept access to localStorage from Iframe, here’s a live jsFiddle demo)
Code:
// 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>