Здравствуйте. Помогите разобраться.
Есть код. При нажатии сочетания shift+alt хотелось бы перерисовывать клавиатуру с одной раскладки на другую. В консоли видно, что значение свойства mode меняется. Но в render() потом всё равно используется первоначальное значение.
https://repl.it/@Ambrance/keyboard
Тут несколько проблем:
У тебя есть метод render
который только один раз синхронизирует состояние класса и состояние DOM при создании клавитатуры. После нет ничего что бы синхронизировало изменившееся состояние класса и DOM.
Бонус проблема: переключение между русской-английской происходит просто по ctrl
А что за связь с ctrl?.. Почему так реагирует? Я ведь явно пишу, какую комбинацию ожидаю
Возможно я должна вызывать его внутри объекта, но как это сделать, если заранее не известны аргументы…
Дело не в ctrl
, а в самом подходе. Не нужно аккумулировать нажатые клавиши в сет. Задолбаешься обрабатывать это состояние корректно. У события нажатия есть флаги которые говорят о том какая клавиша нажата (типа зажат ли шифт или альт) вот на них и смотри:
document.addEventListener('keydown', (event) => {
if (event.shiftKey && event.altKey) {
alert('Opa!')
}
})
Единственное что я не проверять кроссбраузерности тех свойств что использовал
изначально пробовала так, но что-то не получилось. Попытаюсь еще раз.
На самом деле есть несколько проблем. (в примере есть решение “в лоб”, вродь переключается и ререднерит)
- Рендер надо запускать несколько раз исходя из начальной имплементации, а runOnKeys один раз.
- фільтер і клір можна заменить на every + has
- лучше иметь в классе функционал описивающий кнтейнер, и весь функционал инициализации. Я б посоветовал только класс принимать в контструкторе и строить на сонове него клаву.
П.С. Сорян если встрял в разговор, просто хотелось чуток чет подкодить . )))
Мысль я поняла, правда в примере не работает у меня, когда открываю.
Спасибо)
Норм практика для компонент передавать аргументов корневой узел компоненты и “прикапывать” его в инстансе класса.
Это позволит написать такой метод render
, который будет “переносить” внутреннее состояние компонента в DOM узел из this
. Структурно это должно выглядеть как-то так:
class Keyboard() {
constructor(options) {
this.domNode = options.domNode
this.render()
window.addEventListener('keyup', this.keyupHandler.bind(this))
}
changeMode() {
// set new state
this.render()
}
keyupHandler() {
if (needToChangeMode) {
this.changeMode()
}
}
render() {
// state -> DOM node
}
}
Все правильно. Чем больше описаний перспектив одного и того же, тем проще понять о чем речь.
Это верный путь, его нужно “додавить”. Путь с аккумуляцией состояния в Set
-e неправильный потому что ведет к хрупкому коду.
Делаю по вашему примеру. Правда пришлось сменить сочетание на shift+ctrl (не воспринимает shift+alt - может дело в линуксе), и keyup на keydown.
Всё равно рендерит английский вариант. Что я упускаю?
https://repl.it/@Ambrance/keyboard
Во-первых. Нужно подчищать DOM с предыдущего состояния. Сейчас новые кнопки просто добавляются к существующим.
Во-вторых я не вижу где ты используешь значения для кнопок из this.mode
в render
. Нужно жеж не this.keys
, a this.mode.keys
. Сейчас this.keys
записывается один раз в конструкторе и последующие изменения this.mode
никак на них не влияют.
Это я знаю, специально закомментировала строку, чтобы видеть, что отрисовка есть.
Того, что в конструкторе есть this.keys = this.mode.keys; недостаточно? Нужно внутри метода явно писать this.mode.keys?
UPD: видимо так и есть… Объявления в конструкторе были лишними
Искренне благодарю! Наконец получилось)