对键盘事件使用 elm 高阶函数
Using elm higher order functions for keyboard events
我正在尝试创建一个高阶函数来创建仅捕获特定键码的函数。该代码的灵感来自 Evan 的 onEnter
函数,来自他的 todomvc 实现,该实现仅捕获输入函数。
onKeyCode : Int -> Msg -> Attribute Msg
onKeyCode keycode msg =
let
captureKey code =
if code == keycode then
msg
else
NoOp
in
on "keydown" (Json.map captureKey keyCode)
onEnter = onKeyCode 13
onEsc = onKeyCode 27
现在我想将其添加到查看器中的输入组件:
input
[ class "edit"
, id ("todo-" ++ toString item.uid)
, value item.message
, onInput (UpdateItem item.uid)
, onBlur (SwitchEditTodo item.uid False)
, onEnter (SwitchEditTodo item.uid False)
, onEsc (UndoEditTodo item.uid)
]
[]
如果我只有 onEnter
,代码将按预期工作,但如果我添加 onEsc
,则永远不会执行 onEnter
代码。我在哪里做错了?这是高阶函数上下文或在不同函数中具有多个值的“on”映射的问题吗?
您正在向输入元素添加两个 onkeydown
属性,并且只有其中一个可以获胜。列表中的第二个覆盖第一个。如果在幕后使用addEventListener
,情况就不会这样了,但现在我们可以用稍微不同的方法来解决它。
您可以编写一个 onKeysDown
函数来接受可能的键码列表以及它们应该调用的消息,如下所示:
onKeysDown : List (Int, Msg) -> Attribute Msg
onKeysDown keys =
let
captureKey code =
List.filterMap (\(k, m) -> if k == code then Just m else Nothing) keys
|> List.head
|> Maybe.withDefault NoOp
in
on "keydown" (Json.map captureKey keyCode)
然后您可以编写 shorthand 函数来处理特定的键,如下所示:
enter msg = (13, msg)
esc msg = (27, msg)
现在您可以像这样在您的视图中使用它:
input
[ ...
, onKeysDown
[ enter <| SwitchEditTodo item.uid False
, esc <| UndoEditTodo item.uid
]
]
之所以有效,是因为它生成了一个 keydown
事件处理程序属性。当您用预定义的元组替换高阶函数时,它仍然为您提供同样可读的代码。
我正在尝试创建一个高阶函数来创建仅捕获特定键码的函数。该代码的灵感来自 Evan 的 onEnter
函数,来自他的 todomvc 实现,该实现仅捕获输入函数。
onKeyCode : Int -> Msg -> Attribute Msg
onKeyCode keycode msg =
let
captureKey code =
if code == keycode then
msg
else
NoOp
in
on "keydown" (Json.map captureKey keyCode)
onEnter = onKeyCode 13
onEsc = onKeyCode 27
现在我想将其添加到查看器中的输入组件:
input
[ class "edit"
, id ("todo-" ++ toString item.uid)
, value item.message
, onInput (UpdateItem item.uid)
, onBlur (SwitchEditTodo item.uid False)
, onEnter (SwitchEditTodo item.uid False)
, onEsc (UndoEditTodo item.uid)
]
[]
如果我只有 onEnter
,代码将按预期工作,但如果我添加 onEsc
,则永远不会执行 onEnter
代码。我在哪里做错了?这是高阶函数上下文或在不同函数中具有多个值的“on”映射的问题吗?
您正在向输入元素添加两个 onkeydown
属性,并且只有其中一个可以获胜。列表中的第二个覆盖第一个。如果在幕后使用addEventListener
,情况就不会这样了,但现在我们可以用稍微不同的方法来解决它。
您可以编写一个 onKeysDown
函数来接受可能的键码列表以及它们应该调用的消息,如下所示:
onKeysDown : List (Int, Msg) -> Attribute Msg
onKeysDown keys =
let
captureKey code =
List.filterMap (\(k, m) -> if k == code then Just m else Nothing) keys
|> List.head
|> Maybe.withDefault NoOp
in
on "keydown" (Json.map captureKey keyCode)
然后您可以编写 shorthand 函数来处理特定的键,如下所示:
enter msg = (13, msg)
esc msg = (27, msg)
现在您可以像这样在您的视图中使用它:
input
[ ...
, onKeysDown
[ enter <| SwitchEditTodo item.uid False
, esc <| UndoEditTodo item.uid
]
]
之所以有效,是因为它生成了一个 keydown
事件处理程序属性。当您用预定义的元组替换高阶函数时,它仍然为您提供同样可读的代码。