Как я могу получить Dynamic Bool, который соответствует тому, что мышь находится над определенным элементом?
Предположим, у меня есть кнопка и квадрат, например:
main = mainWidget $ do
x <- button "Change color."
y <- toggle False x
z <- mapDyn style y
elDynAttr "div" z blank
style :: Bool -> Map String String
style b | b = "style" =: "height: 10ex; width: 10ex; background-color: #f00;"
| otherwise = "style" =: "height: 10ex; width: 10ex; background-color: #900;"
Цвет квадрата будет чередоваться между ярким и темно-красным при нажатии кнопки.
Я хочу заменить кнопку зеленым прямоугольником таким образом, чтобы при наведении на нее указателя мыши красный квадрат был ярким, в противном случае - темным. Для получения бонусных баллов я бы хотел, чтобы зеленый прямоугольник был div tabindex=0
и чтобы убедиться, что красный квадрат яркий, когда он сфокусирован, но, как только я пойму общий подход, я, вероятно, смогу понять это сам.
Я предполагаю, что есть некоторый API, который позволяет добавлять обработчики событий в el
, но я пока не нашел. А может, вообще есть другой подход, который я не мог знать?
1 ответ
Все, что вам нужно, находится в Reflex.Dom.Widget.Basic
, Если вы создаете виджет с функцией, которая имеет простое в своем имени, например, el'
, вы можете получить объект типа El
, который является членом HasDomEvent
, domEvent
единственный метод этого класса, позволяет извлекать поток событий, соответствующий одному из выбранных имён событий. Смешивание событий и преобразование их в соответствующий Dynamic
затем делается с помощью обычного инструмента Reflex, найденного в Reflex.Class
а также Reflex.Dynamic
, Вам необходимо ознакомиться с этими интерфейсами, но есть полезный краткий справочник.
(Обязательно используйте документацию, соответствующую версии Reflex, для которой вы создаете версию, так как между версиями имеются значительные изменения.)
Один из способов кодирования вашего дела заключается в следующем:
main = mainWidget $ do
y <- greenBox
z <- mapDyn style y
elDynAttr "div" z blank
style :: Bool -> Map String String
style ... -- Abridged for brevity.
greenBox :: MonadWidget t m => m (Dynamic t Bool)
greenBox = do
(e, _) <- elAttr' "div" ("style" =: "height: 10ex; width: 10ex; background-color: #0c0;") blank
let
eEnter = domEvent Mouseenter e
eLeave = domEvent Mouseleave e
holdDyn False . leftmost $ [True <$ eEnter, False <$ eLeave]
Здесь мы создаем виджет для зеленого поля, который возвращает Dynamic, указывающий, активирован ли он. Все остальное так же, как в вашем первоначальном примере.
Спасибо /u/dalaing за советы по этому вопросу.