Как применить localStorage для выбора параметров и classList.add? - PullRequest
0 голосов
/ 25 апреля 2020

Примечание: я использую только ваниль JS.

Мои параметры выбора вызывают classList.add примерно так

CSS:

body{font-family:arial}
body.uppercase {text-transform:uppercase}
body.comicsans {font-family:comic sans ms}

HTML:

<select class="option" id="test" name="test" onchange="selectFonts(this)">
<option value="arial">Arial</option>
<option value="uppercase">Uppercase</option>
<option value="comicsans">Comic sans (dyslexic friendly)</option>

Скрипт (# 1):

function selectFonts(element) {
const a = element.options[element.selectedIndex].value;

if(a == "arial") {
[].map.call(document.querySelectorAll('body'), function(el) {
el.classList.remove("uppercase","comicsans"); el.classList.add('arial');});
}

if(a == "uppercase") {
[].map.call(document.querySelectorAll('body'), function(el) {
el.classList.remove("comicsans","arial");el.classList.add("uppercase"); });
}

if(a == "comicsans") {
[].map.call(document.querySelectorAll('body'), function(el) {
el.classList.remove("uppercase","arial");el.classList.add('comicsans'); }); 
}

}

Все работает нормально. Теперь я пытаюсь добавить localStorage, чтобы параметры и добавленный класс оставались на refre sh, добавив следующий скрипт.

Script (# 2)

document.getElementById("test").onchange = function() {
localStorage['test'] = document.getElementById("test").value;}

window.onload= function() {
if(localStorage['test'])
document.getElementById("test").value = localStorage['test']; }.

Script # 2 работает, выбранный параметр остается тем же при refre sh, однако он отключает сценарий # 1 - классы не добавляются.

Для пояснения, оба сценария работают при использовании по отдельности, но не вместе. # 2 отменяет # 1.

Есть ли способ заставить их обоих работать вместе?

Вот рабочий jsfiddle со скриптом # 1 (добавление классов)

и jsbin скрипта # 2 (localalstorage)

Ответы [ 2 ]

1 голос
/ 25 апреля 2020

Проблема очень проста. Каждый элемент HTML (и соответствующий ему элемент DOM) может иметь только одно из каждого свойства, включая свойства обработчика, например onchange.

. Таким образом, ваш второй скрипт по существу перезаписывает элемент onchange элемента select, а ваш перестает работать первый скрипт

Вот тут и приходит .addEventListener(). Это метод, который добавляет обработчики событий - без перезаписи других:

//Await the DOM to be loaded - just like window.onload, but triggers faster
document.addEventListener('DOMContentLoaded', ()=>{
  //Note that it's change, not onchange:
  document.getElementById("test").addEventListener('change', selectFonts)
})

Перепроектируйте selectFonts, чтобы заставить его работать в этом случае:

//I've simplified you code a bit...
function selectFonts(){
  const element = document.getElementById("test")
  const selected = element.options[element.selectedIndex].value;

  //We do the same things for each value - so, let's simplify:

  //Remove all classes
  for(const font of ['arial', 'uppercase', 'comicsans'])
    document.body.classList.remove(font)
  //Add the active class
  document.body.classList.add(selected)
}

И ваш второй код:

document.addEventListener('DOMContentLoaded', ()=>{
  document.getElementById("test").addEventListener('change', function() {
    const element = document.getElementById("test")
    const selected = element.options[element.selectedIndex].value;
    window.localStorage.setItem('test', selected)
  })

  const selected = window.localStorage.getItem('test')
  if(selected){
    for(const elem of document.getElementById("test").options){
      if(selected === elem.value){
        elem.selected = true
        break
      }
    }
    document.body.classList.add(selected)
  }
})

Смотрите его вживую на codepen.io

1 голос
/ 25 апреля 2020

Change событие не запускается, когда вы устанавливаете значение для select. Значение в выборе обновляется, но стили не применяются.

Вместо двух функций вы можете установить выбранное значение на localstorage в скрипте (# 1) и разделить функцию selectFonts на один для получения выбранного значения и другой для установки стилей. Надеюсь, что приведенный ниже код поможет.

function selectFonts(element) {
const a = element.options[element.selectedIndex].value;

setStyles(a);

localStorage['test'] = a;

}


function setStyles(a) {
if(a == "arial") {
[].map.call(document.querySelectorAll('body'), function(el) {
el.classList.remove("uppercase","comicsans"); el.classList.add('arial');});
}

if(a == "uppercase") {
[].map.call(document.querySelectorAll('body'), function(el) {
el.classList.remove("comicsans","arial");el.classList.add("uppercase"); });
}

if(a == "comicsans") {
[].map.call(document.querySelectorAll('body'), function(el) {
el.classList.remove("uppercase","arial");el.classList.add('comicsans'); }); 
}
}

window.onload= function() {
if(localStorage['test'])
document.getElementById("test").value = localStorage['test']; 
setStyles(localStorage['test'])
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...