Переключатель оформления на примитивном javascript
Здравствуйте, помогите, пожалуйста, разобраться с проблемой.
Пишу скрипт для переключения оформления сайта. Принципиальная схема такая: Есть кнопка, при нажатии которой добавляются классы в body, и изымается дефолтный. При необходимости посетитель может понажимать дополнительно появившиейся кнопки для изменения размера шрифта, и цветового оформления. Написанный ранее скрипт работает на всех браузерах, кроме злополучного IE8 и ранее, поскольку использованы были такие свойства как classlist, например. Пробовал внедрить разные библиотеки, polyfill, но единственное к чему это привело, так это к тому, что сайт стал жутко долго грузиться. В связи с этим, решил что лучше всего будет переписать скрипт, используя более примитивный синтаксис, но пробелы в знаниях не позволяют реализовать задумку. На мой взгляд, основная проблема состоит в том, что я записываю в localstorage три разных типа (с логической точки зрения) классов, которые должны менять разные свойства отображения, обращаясь в CSS-файл, и тут возникает конфликт. Сделал вывод localstorage в консоль и постоянно наблюдаю одну и ту же картину: один и тот же класс записан в несколько раз. Разными путями пытался решить проблему и уже запутался, так что, вполне допускаю, что на данный момент в коде присутствуют повторения или лишние команды. Итак, вот так выглядит код на данный момент: function hasClass(el, className) { if (el.classList) return el.classList.contains(className) else return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)')) } function addClass(el, className) { if (el.classList) el.classList.add(className) else if (!hasClass(el, className)) el.className += " " + className } function removeClass(el, className) { if (el.classList) el.classList.remove(className) else if (hasClass(el, className)) { var reg = new RegExp('(\\s|^)' + className + '(\\s|$)') el.className=el.className.replace(reg, ' ') } } function addstyle(className){ var bodyver = document.getElementsByTagName("body")[0]; addClass(bodyver, className); localStorage.setItem("statever", className); } function addcolor(className){ var bodycol = document.getElementsByTagName("body")[0]; addClass(bodycol, className); localStorage.setItem("statecol", className); } function addsize(className){ var bodysize = document.getElementsByTagName("body")[0]; addClass(bodysize, className); localStorage.setItem("statesize", className); } function clearstyle(className){ var bodyclear = document.getElementsByTagName("body")[0]; removeClass(bodyclear, className); localStorage.removeItem("className"); } <button onclick="addstyle('style-c'); addstyle('style-a'); addstyle('style-blackfont-whitebgr'); clearstyle('style-norm');" class="style-c" id="click-style-c" style="font-size:18px; background:none; border:none;">Кнопка вызова дополнительной панели</button> <!--При клике появляется вот это !--> <p style="font-size:30px; text-align:center;">Размер:<button onclick="addsize('style-a'); clearstyle('style-aa'); clearstyle('style-aaa');" class="style-a" style="font-size:30px; background:none; border:none;">А</button> <button onclick="addsize('style-aa'); clearstyle('style-a'); clearstyle('style-aaa');" class="style-aa" style="font-size:40px; background:none; border:none;">А</button> <button onclick="addsize('style-aaa'); clearstyle('style-a'); clearstyle('style-aa');" class="style-aaa" style="font-size:50px; background:none; border:none;">А</button> Цвет:<button onclick="addcolor('style-blackfont-whitebgr'); clearstyle('style-whitefont-greenbgr'); clearstyle('style-whitefont-blackbgr');" class="style-blackfont-whitebgr" style="font-size:50px; color:black; background:white; border:black;">А</button> <button onclick="clearstyle('style-blackfont-whitebgr'); addcolor('style-whitefont-greenbgr'); clearstyle('style-whitefont-blackbgr');" class="style-whitefont-greenbgr" style="font-size:50px; color:white; background:green; border:black;">А</button> <button onclick="clearstyle('style-blackfont-whitebgr'); clearstyle('style-whitefont-greenbgr'); addcolor('style-whitefont-blackbgr');" class="style-whitefont-blackbgr" style="font-size:50px; color:white; background:black; border:black;">А</button> <button onclick="addstyle('style-norm'); clearstyle('style-c'); clearstyle('style-a'); clearstyle('style-aa'); clearstyle('style-aaa'); clearstyle('style-blackfont-whitebgr'); clearstyle('style-whitefont-greenbgr'); clearstyle('style-whitefont-blackbgr');" class="style-norm" style="font-size:30px; background:none; border:none;">Обычная версия</button></p> var statever = localStorage.getItem("statever"); addstyle(!!statever ? statever : "style-norm"); var statecol = localStorage.getItem("statecol"); addcolor(!!statecol ? statecol : "style-norm"); var statesize = localStorage.getItem("statesize"); addsize(!!statesize ? statesize : "style-norm"); console.log(statever); console.log(statecol); console.log(statesize); var bodyclassstylec = localStorage.getItem("statever"); if (bodyclassstylec.className = 'style-c'){ localStorage.getItem("statever"); localStorage.getItem("statecol"); localStorage.getItem("statesize"); removeClass(bodyclassstylec, 'style-norm'); localStorage.removeItem('style-norm'); } var bodyclassstylenorm = localStorage.getItem("statever"); if (bodyclassstylenorm.className != 'style-c'){ addClass(typeofbody, 'style-norm'); removeClass(bodyclassstylenorm, 'style-c'); removeClass(bodyclassstylenorm, 'style-a'); removeClass(bodyclassstylenorm, 'style-aa'); removeClass(bodyclassstylenorm, 'style-aaa'); removeClass(bodyclassstylenorm, 'style-blackfont-whitebgr'); removeClass(bodyclassstylenorm, 'style-whitefont-greenbgr'); removeClass(bodyclassstylenorm, 'style-whitefont-blackbgr'); localStorage.removeItem('style-c'); localStorage.removeItem('style-a'); localStorage.removeItem('style-aa'); localStorage.removeItem('style-aaa'); localStorage.removeItem('style-blackfont-whitebgr'); localStorage.removeItem('style-whitefont-greenbgr'); localStorage.removeItem('style-whitefont-blackbgr'); } var bodyclassstylea = localStorage.getItem("statesize"); if (bodyclassstylea.className = "style-a"){ addClass(bodyclassstylea, 'style-c'); removeClass(bodyclassstylea, 'style-aa'); removeClass(bodyclassstylea, 'style-aaa'); localStorage.removeItem('style-aa'); localStorage.removeItem('style-aaa'); } var bodyclassstyleaa = localStorage.getItem("statesize"); if (bodyclassstyleaa.className = "style-aa"){ addClass(bodyclassstyleaa, 'style-c'); removeClass(bodyclassstyleaa, 'style-a'); removeClass(bodyclassstyleaa, 'style-aaa'); localStorage.removeItem('style-a'); localStorage.removeItem('style-aaa'); } var bodyclassstyleaaa = localStorage.getItem("statesize"); if (bodyclassstyleaaa.className = "style-aaa"){ addClass(bodyclassstyleaaa, 'style-c'); removeClass(bodyclassstyleaaa, 'style-a'); removeClass(bodyclassstyleaaa, 'style-aa'); localStorage.removeItem('style-a'); localStorage.removeItem('style-aa'); } var bodyclassstylebw = localStorage.getItem("statecol"); if (bodyclassstylebw.className = "style-blackfont-whitebgr"){ addClass(bodyclassstylebw, 'style-c'); removeClass(bodyclassstylebw, 'style-whitefont-greenbgr'); removeClass(bodyclassstylebw, 'style-whitefont-blackbgr'); localStorage.removeItem('style-whitefont-greenbgr'); localStorage.removeItem('style-whitefont-blackbgr'); } var bodyclassstylewg = localStorage.getItem("statecol"); if (bodyclassstylewg.className = "style-whitefont-greenbgr"){ addClass(bodyclassstylewg, 'style-c'); removeClass(bodyclassstylewg, 'style-blackfont-whitebgr'); removeClass(bodyclassstylewg, 'style-whitefont-blackbgr'); localStorage.removeItem('style-blackfont-whitebgr'); localStorage.removeItem('style-whitefont-blackbgr'); } var bodyclassstylewb = localStorage.getItem("statecol"); if (bodyclassstylewb.className = "style-whitefont-blackbgr"){ addClass(bodyclassstylewb, 'style-c'); removeClass(bodyclassstylewb, 'style-blackfont-whitebgr'); removeClass(bodyclassstylewb, 'style-whitefont-greenbgr'); localStorage.removeItem('style-blackfont-whitebgr'); localStorage.removeItem('style-whitefont-greenbgr'); }; Само по себе переключение в рамках одной страницы работает так как нужно, но если обновить страницу или перейти на соседнюю, то и в localstorage остается бардак, и как следствие в классах body постоянно находятся противоречащие необходимому результату классы. логика конечного результата по классам такова: Если нужна обычная версия, то должен сохраняться класс style-norm. Если же нужно убрать лишнее оформление, то style-norm исключается, и ему на смену приходит style-c. При Нажатии кнопки вызова доп.панели прописываются так же style-a и style-blackfont-whitebgr. Далее размер шрифтов регулируется классами style-a, style-aa, style-aaa (они друг друга исключают, а так же одновременно с ними не должен существовать класс style-norm, и обязательно должен быть style-c). Цвет шрифтов регулируется классами style-blackfont-whitebgr, style-whitefont-blackbgr, style-whitefont-greenbgr (они друг друга исключают, а так же одновременно с ними не должен существовать класс style-norm, и обязательно должен быть style-c). Простите, за огромное количества текста, я никого не держу за идиота - просто я то свою логику понимаю, а вот из кода (тем более, что раз уж он не работает так, как мне необходимо) может быть не всё очевидно. |
Описка в функции clearstyle:
localStorage.removeItem("className"); Скорее всего ожидалось localStorage.removeItem(className); Откуда-то вылезли удаления из localStorage того чего там никогда не было записано: localStorage.removeItem('style-norm'); Почти каждый if делает присваивание вместо сравнения: bodyclassstylec.className = 'style-c' Тут скорее всего предполагалось проверять есть ли такой класс. Без classList это можно сделать так: bodyclassstylec.className.match(/style-c/); Вместо этого: document.getElementsByTagName("body")[0] достаточно document.body Как работает функция addClass осталось загадкой. Рекомендую посмотреть на какой-нибудь js unit testing инструмент (Jest), если хотите быть уверены, что ваш код вообще работает так, как предполагалось. |
По функции addClass дополнил исходное сообщение.
|
var bodyclassstylenorm = localStorage.getItem("statever"); Тут bodyclassstylenorm будет строкой, поэтому условие типа if (bodyclassstylenorm.className != 'style-c'){ не работает. Попробуйте сравнить со строкой: if (bodyclassstylenorm !== 'style-c'){ И таких мест 8 штук. Вообще localStorage всегда хранит свои записи в формате строки, поэтому если хочется хранить что-то другое можно использовать JSON.parse и JSON.stringify при чтении и записи соответственно. |
Цитата:
|
Цитата:
|
Но я тогда не очень понимаю понимаю почему происходит так, что по моей логике в statever может быть записано либо style-c либо style-norm, а по факту в консоли у меня выводится другой класс. Или еще бывает все три записи style-norm.
|
Глупая ошибка была!
Я сам же по кнопке вызываю не ту функцию! С записями в localstorage вроде все наладилось. Но при обновлении до сих пор не сохраняется выбранная совокупность классов. Нужно ведь из localstorage запрашивать, верно? |
Этот код можно существенно сократить используя циклы.
|
Проблема решена! Огромное спасибо за помощь.
На всякий случай, оставлю итоговый код, вдруг кому-то пригодится. Он, конечно, не идеален, но работает без подключения дополнительных библиотек. Только что проверил на IE8, всё переключается так, как задумано! function hasClass(el, className) { if (el.classList) return el.classList.contains(className) else return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)')) } function addClass(el, className) { if (el.classList) el.classList.add(className) else if (!hasClass(el, className)) el.className += " " + className } function removeClass(el, className) { if (el.classList) el.classList.remove(className) else if (hasClass(el, className)) { var reg = new RegExp('(\\s|^)' + className + '(\\s|$)') el.className=el.className.replace(reg, ' ') } } function addstyle(className){ var bodyver = document.getElementsByTagName("body")[0]; addClass(bodyver, className); localStorage.setItem("statever", className); } function addcolor(className){ var bodycol = document.getElementsByTagName("body")[0]; addClass(bodycol, className); localStorage.setItem("statecol", className); } function addsize(className){ var bodysize = document.getElementsByTagName("body")[0]; addClass(bodysize, className); localStorage.setItem("statesize", className); } function clearstyle(className){ var bodyclear = document.getElementsByTagName("body")[0]; removeClass(bodyclear, className); localStorage.removeItem(className); } <div class="style-form" style="margin:0; padding:0; position:fixed; top:60px; right:20px; z-index:99999;"> <button onclick="addsize('style-a'); addcolor('style-blackfont-whitebgr'); addstyle('style-c'); clearstyle('style-norm');" class="style-c" id="click-style-c" style="font-size:18px; background:none; border:none;">Включить доп.панель</button> </div> <!-- Панель доп.изменений !--> <div class="panel-style-c"> <p style="font-size:30px; text-align:center;">Размер:<button onclick="addsize('style-a'); clearstyle('style-aa'); clearstyle('style-aaa');" class="style-a" style="font-size:30px; background:none; border:none;">А</button> <button onclick="addsize('style-aa'); clearstyle('style-a'); clearstyle('style-aaa');" class="style-aa" style="font-size:40px; background:none; border:none;">А</button> <button onclick="addsize('style-aaa'); clearstyle('style-a'); clearstyle('style-aa');" class="style-aaa" style="font-size:50px; background:none; border:none;">А</button> Цвет:<button onclick="addcolor('style-blackfont-whitebgr'); clearstyle('style-whitefont-greenbgr'); clearstyle('style-whitefont-blackbgr');" class="style-blackfont-whitebgr" style="font-size:50px; color:black; background:white; border:black;">А</button> <button onclick="clearstyle('style-blackfont-whitebgr'); addcolor('style-whitefont-greenbgr'); clearstyle('style-whitefont-blackbgr');" class="style-whitefont-greenbgr" style="font-size:50px; color:white; background:green; border:black;">А</button> <button onclick="clearstyle('style-blackfont-whitebgr'); clearstyle('style-whitefont-greenbgr'); addcolor('style-whitefont-blackbgr');" class="style-whitefont-blackbgr" style="font-size:50px; color:white; background:black; border:black;">А</button> <button onclick="addstyle('style-norm'); clearstyle('style-c'); clearstyle('style-a'); clearstyle('style-aa'); clearstyle('style-aaa'); clearstyle('style-blackfont-whitebgr'); clearstyle('style-whitefont-greenbgr'); clearstyle('style-whitefont-blackbgr');" class="style-norm" style="font-size:30px; background:none; border:none;">Обычная версия</button></p> </div> var statever = localStorage.getItem("statever"); addstyle(!!statever ? statever : "style-norm"); var statecol = localStorage.getItem("statecol"); addcolor(!!statecol ? statecol : ""); var statesize = localStorage.getItem("statesize"); addsize(!!statesize ? statesize : ""); console.log(statever); console.log(statecol); console.log(statesize); var bodyclassstylec = document.body; if (statever == 'style-c'){ localStorage.getItem("statever"); localStorage.getItem("statecol"); localStorage.getItem("statesize"); removeClass(bodyclassstylec, "style-norm"); localStorage.removeItem("style-norm"); } var bodyclassstylenorm = document.body; if (statever !== 'style-c'){ removeClass(bodyclassstylenorm, "style-c"); removeClass(bodyclassstylenorm, "style-a"); removeClass(bodyclassstylenorm, "style-aa"); removeClass(bodyclassstylenorm, "style-aaa"); removeClass(bodyclassstylenorm, "style-blackfont-whitebgr"); removeClass(bodyclassstylenorm, "style-whitefont-greenbgr"); removeClass(bodyclassstylenorm, "style-whitefont-blackbgr"); addClass(bodyclassstylenorm, "style-norm"); localStorage.removeItem("style-c"); localStorage.removeItem("style-a"); localStorage.removeItem("style-aa"); localStorage.removeItem("style-aaa"); localStorage.removeItem("style-blackfont-whitebgr"); localStorage.removeItem("style-whitefont-greenbgr"); localStorage.removeItem("style-whitefont-blackbgr"); } var bodyclassstylea = document.body; if (bodyclassstylea == 'style-a'){ addClass(bodyclassstylea, 'style-c'); removeClass(bodyclassstylea, "style-aa"); removeClass(bodyclassstylea, "style-aaa"); removeClass(bodyclassstylea, "style-norm"); localStorage.removeItem("style-aa"); localStorage.removeItem("style-aaa"); localStorage.removeItem("style-norm"); } else if (bodyclassstylea == 'style-aa'){ addClass(bodyclassstylea, 'style-c'); removeClass(bodyclassstylea, "style-a"); removeClass(bodyclassstylea, "style-aaa"); removeClass(bodyclassstylea, "style-norm"); localStorage.removeItem("style-a"); localStorage.removeItem("style-aaa"); localStorage.removeItem("style-norm"); } else if (bodyclassstylea =='style-aaa'){ addClass(bodyclassstylea, 'style-c'); removeClass(bodyclassstylea, "style-a"); removeClass(bodyclassstylea, "style-aa"); removeClass(bodyclassstylea, "style-norm"); localStorage.removeItem("style-a"); localStorage.removeItem("style-aa"); localStorage.removeItem("style-norm"); } var bodyclassstyle = document.body; if (bodyclassstyle == 'style-blackfont-whitebgr'){ addClass(bodyclassstyle, 'style-c'); removeClass(bodyclassstyle, "style-whitefont-greenbgr"); removeClass(bodyclassstyle, "style-whitefont-blackbgr"); localStorage.removeItem("style-whitefont-greenbgr"); localStorage.removeItem("style-whitefont-blackbgr"); localStorage.removeItem("style-norm"); }else if (bodyclassstyle == 'style-whitefont-greenbgr'){ addClass(bodyclassstyle, "style-c"); removeClass(bodyclassstyle, "style-blackfont-whitebgr"); removeClass(bodyclassstyle, "style-whitefont-blackbgr"); localStorage.removeItem("style-blackfont-whitebgr"); localStorage.removeItem("style-whitefont-blackbgr"); localStorage.removeItem("style-norm"); } else if (bodyclassstyle == 'style-whitefont-blackbgr'){ addClass(bodyclassstyle, "style-c"); removeClass(bodyclassstyle, "style-blackfont-whitebgr"); removeClass(bodyclassstyle, "style-whitefont-greenbgr"); localStorage.removeItem("style-blackfont-whitebgr"); localStorage.removeItem("style-whitefont-greenbgr"); localStorage.removeItem("style-norm"); } |
Часовой пояс GMT +3, время: 00:45. |