Почему темная тема может мелькать, переходя по страницам сайта?

12
Dmitriy_2014
На сайте с 01.07.2014
Offline
344
422

Всем привет!

Экспериментирую и хочу сделать самую простую версию переключения темы, использую этот кейс - https://frontendtoday.ru/articles/dark-mode-best-practice/, вроде простой вариант с щелчком по кнопке и вроде все работает и вроде все устраивает, но есть баги.

Код оттуда же:

const button = document.querySelector('.button')

const currentTheme = localStorage.getItem('theme') || 'light'


button.addEventListener('click', function () {

  const theme = localStorage.getItem('theme')

  document.documentElement.setAttribute(

    'data-theme',

    theme === 'light' ? 'dark' : 'light',

  )

  localStorage.setItem('theme', theme === 'light' ? 'dark' : 'light')

})


document.documentElement.setAttribute('data-theme', currentTheme)

Но происходит следующее:

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

Я ещё сначала обернул все это в jQuery(document).ready, так оно мигало при каждом переходе, потом убрал document.ready и вроде перестало, но все равно иногда подмигивает.

Может быть это из-за того что js файл в футере, или этот код лучше перенести как-то в хеад перед вызовом css файла стилей. Или это связано с кешем, я уж и не знаю…

Заранее всем спасибо за ответы!


Темный режим и как его лучше делать — Фронтенд сегодня
Темный режим и как его лучше делать — Фронтенд сегодня
  • frontendtoday.ru
Вы, наверное, уже заметили, что в последнее время все начали предлагать своим пользователям темный режим (Dark Mode), в котором в основном используются темные цвета, вместо традиционных белых и ярких тонов. Темный режим сегодня является одним из самых главных тенденций в современном дизайне пользовательского интерфейса. Операционные системы...
D
На сайте с 02.02.2010
Offline
142
#1
Если сайт на php, то лучше сразу атрибут добавлять, например в body. Тоесть js использовать для установки и удаления атрибута и запись в куки, а php нужен для установки атрибута сразу при загрузки страницы, чтобы ничего не моргало.
lutskboy
На сайте с 22.11.2013
Offline
184
#2
можно добавить  body visibility hidden а при установке темы    visibility visible
W1
На сайте с 22.01.2021
Offline
306
#3
Dmitriy_2014 :
обернул все это в jQuery(document).ready, так оно мигало при каждом переходе

Естественно. Сначала показывается, как написано в исходном коде, потом срабатывает JS.

Dmitriy_2014 :
потом убрал document.ready и вроде перестало, но все равно иногда подмигивает

Ну тоже естественно, потому что исходный CSS  срабатывает  до JS.

Мой форум - https://webinfo.guru –Там я всегда на связи
Dmitriy_2014
На сайте с 01.07.2014
Offline
344
#4
divv #:
Если сайт на php, то лучше сразу атрибут добавлять, например в body. Тоесть js использовать для установки и удаления атрибута и запись в куки, а php нужен для установки атрибута сразу при загрузки страницы, чтобы ничего не моргало.
Сайт то на php, но есть нюанс, используется плагин кэширования и страницы отдаются как бы готовыми. Может это как-то влияет?
Dmitriy_2014
На сайте с 01.07.2014
Offline
344
#5
lutskboy #:
можно добавить  body visibility hidden а при установке темы    visibility visible
Сделать типа как по этому гайду - https://dev.to/whitep4nth3r/the-best-lightdark-mode-theme-toggle-in-javascript-368f, добавив в тег html атрибут data-theme="light"?
The best light/dark mode theme toggle in JavaScript
The best light/dark mode theme toggle in JavaScript
  • 2023.06.20
  • dev.to
Learn how to build The Ultimate Theme Toggle™️ for your website using JavaScript, CSS custom properties, local storage and system settings. No framework required!
Dmitriy_2014
На сайте с 01.07.2014
Offline
344
#6
webinfo #:
Ну тоже естественно, потому что исходный CSS  срабатывает  до JS.
Так, а что сделать, перенести JS до CSS?
Snake800
На сайте с 02.02.2011
Offline
222
#7
Dmitriy_2014 #:
Так, а что сделать, перенести JS до CSS?

Достаточно в head. Проверено. И да, хорошим тоном является при первом визите устанавливать тему на основе дефолтных настроек юзера.

N2
На сайте с 25.04.2024
Offline
29
#8
Если уж решили предложить пользователю выбор темы, возможно, просто опираться на предпочтения юзера на уровне браузера. С помощью media prefer-color-scheme сразу в css отдавать ему темную тему если он юзает ее. Хотя кнопку переключения дополнительно тоже можно. По вопросу, да, дело в том, что скрипт переключает тему после того как стили уже загружены
D
На сайте с 02.02.2010
Offline
142
#9
Dmitriy_2014 #:
Сайт то на php, но есть нюанс, используется плагин кэширования и страницы отдаются как бы готовыми. Может это как-то влияет?

Тогда мой вариант не подойдет.


Еще делают различные прелоадеры на css, которые после полной загрузки html с помощью js удаляются.

Dmitriy_2014
На сайте с 01.07.2014
Offline
344
#10
Snake800 #:

Достаточно в head. Проверено. И да, хорошим тоном является при первом визите устанавливать тему на основе дефолтных настроек юзера.

Да похоже вы правы по поводу head, это вроде работает(даже если скрипт ниже css), я прощелкал 100500 раз, вроде не мелькает вообще. Не, про хороший тон я хочу забыть, т.к. я хочу всего лишь самую простую на белом свете кнопку переключения тем, а она итак превращается в какого-то монстра.

Кстати пару слов о переносе скрипта из футера в хеад, там тоже приколы интересные:

JavaScript говорит мне, что мальчик хочешь на кнопку нажать, а ничего не выйдет, теперь скрипт выше кнопки и поэтому кнопки как бы и нет ХА-ХА – null тебе в ребро :), и в догонку ошибку - Uncaught TypeError: Cannot read properties of null, а ведь до этого все работало когда скрипт был в футере под кнопкой.

Хорошо JavaScript ты не с тем связался, помощь с вестсайдвутангклана подоспела, делаю как этот чувак советует - https://sebhastian.com/javascript-cannot-read-properties-of-null/, ведь мне нужно чтобы теперь кнопка работала со скриптом который в хеад, до кнопки и этот чел советует это:

document.addEventListener('DOMContentLoaded', () => {

  let btnEl = document.getElementById("my-button");

  btnEl?.addEventListener("click", () => alert("You clicked a button!"));

});

И это действительно работает, я не знаю почему и как, но перенос скрипта в хеад и изменение кода как тот чел советовал действительно сработал.

И все вроде бы работает, но все это мне жутко не нравится, ни то что скрипт теперь в хеад, сам скрипт какой-то страшный, плюс 100500 переменных в CSS, лучше бы я ссылку дал на расширение к браузеру Dark Reader, для этих любителей bdsm темных тем, то им в MS-DOS синий экран не нравится, то теперь белый, ну вот они же книги наверное читают, все книги 99% черное на белом, они же не говорят, дайте нам белое на черном, мы же по ночам читаем глазки напрягаем, это же бред какой-то :-), ладно это я шучу :-)
How to fix TypeError: Cannot read properties of null in JavaScript
  • Nathan Sebhastian
  • sebhastian.com
When running JavaScript code, you might encounter an error that says:This error occurs when you try to read a property of an object, but the object itself is actually so the property doesn’t exist. Let me show you an example that causes this error and how I fix it. How to reproduce this error Suppose you write some JavaScript code to select an...
12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий