Я использую Materialize CSS 1.0.0 (поэтому без jQuery), и у меня есть раскрывающийся список, в котором пользователи могут выбирать разные темы (авто, светлая, темная). По умолчанию используется автоматический режим (используются системные настройки пользователя — светлый или темный). На каждой странице есть этот раскрывающийся список. Все работает как надо за исключением того, что если я открываю сайт и захожу в выбор и выбираю, скажем, свет, а потом я перехожу на другую страницу, ввод выбора говорит авто. Однако в раскрывающемся списке выбран свет (в Materialise выбранный элемент имеет серый фон), а затем, когда я закрываю раскрывающийся список, щелкая за его пределами, а не нажимая параметр света, ввод говорит свет.
Итак, чтобы повторить, я выбираю тему, отличную от темы по умолчанию (авто), этот параметр выбран на сайте, но ввод не соответствует выбранному параметру на сайте, пока я не открою раскрывающийся список, где выбрана текущая тема , а затем щелкните за его пределами, после чего ввод будет соответствовать тому, что было выбрано (например, изменится с автоматического на светлый). Это странно, потому что все работает как надо, за исключением того, что ввод изначально не соответствует выбранной опции. Я думаю, это потому, что есть какой-то конфликт между моим JS для переключения тем и «предустановкой» выбора Materialize, которая опирается на свой собственный JS в файле materialize.js. Я протестировал свой код для переключения тем, используя обычный выбор HTML, и он работал отлично. Ввод соответствует выбранному варианту на сайте.
Итак, это должен быть materialize.js и все, что происходит в этом файле. Я попытался просмотреть код в этом файле, чтобы увидеть, можно ли что-то изменить, но я действительно не на том уровне, чтобы понять, что нужно изменить, не сломав все.
Для моего проекта это будет раздражающей маленькой ошибкой.
Вот мой код:
HTML
<div class = "input-field">
<select name = "theme" id = "theme">
<option value = "auto">Auto</option>
<option value = "light">Light</option>
<option value = "dark">Dark</option>
</select>
</div>
<script>
const select = document.querySelector('select');
M.FormSelect.init(select, {});
</script>
CSS
:root {
--dark-background-color: black;
--dark-color: white;
}
body {
/* Light theme */
--background-color: white;
--color: black;
background-color: var(--background-color);
color: var(--color);
}
body.theme-dark {
--background-color: var(--dark-background-color);
--color: var(--dark-color);
}
@media (prefers-color-scheme: dark) {
body.theme-auto {
--background-color: var(--dark-background-color);
--color: var(--dark-color);
}
}
.input-field input {
color: var(--color);
}
JS
function applyTheme(theme) {
document.body.classList.remove('theme-auto', 'theme-light', 'theme-dark');
document.body.classList.add(`theme-${theme}`);
}
document.addEventListener('DOMContentLoaded', () => {
const savedTheme = localStorage.getItem('theme') || 'auto';
applyTheme(savedTheme);
for (const optionElement of document.querySelectorAll('#theme option')) {
optionElement.selected = savedTheme === optionElement.value;
}
document.querySelector('#theme').addEventListener('change', function() {
localStorage.setItem('theme', this.value);
applyTheme(this.value);
});
});
Материализовать JS для выбора: Обновлено: я думаю, что сузил его до оскорбительного кода.
/**
* Handle Input Click
*/
}, {
key: "_handleInputClick",
value: function _handleInputClick() {
if (this.dropdown && this.dropdown.isOpen) {
this._setValueToInput();
this._setSelectedStates();
}
}
// Add input dropdown
this.input = document.createElement('input');
$(this.input).addClass('select-dropdown dropdown-trigger');
this.input.setAttribute('type', 'text');
this.input.setAttribute('readonly', 'true');
this.input.setAttribute('data-target', this.dropdownOptions.id);
if (this.el.disabled) {
$(this.input).prop('disabled', 'true');
}
this.$el.before(this.input);
this._setValueToInput();
Решение может состоять в том, чтобы не использовать Materialize. Думаю, мне просто интересно, сможет ли кто-нибудь, более знакомый с базовой механикой Materialize (его JS), найти здесь исправление.
Вот GIF проблемы в действии



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Добавил это в свой JS.
// added
const themeSelect = document.getElementById('theme');
const savedTheme = localStorage.getItem('theme');
if (savedTheme) themeSelect.value = savedTheme;
themeSelect.addEventListener('change', function () {
localStorage.setItem('theme', this.value);
});
Странно то, что это решение кажется избыточным. Исходный JS из вопроса (не materialize.js) должен делать то же самое, но он этого не делает, но затем добавляет это и, наконец, берет под контроль ввод из файла materialize.js. Возможно, их можно объединить без потери исправления. Мы можем никогда не узнать.