使用elm高阶函数进行键盘事件 [英] Using elm higher order functions for keyboard events
问题描述
我正在尝试创建一个更高阶的函数来创建仅捕获特定键代码的函数。该代码的灵感来自于他的todomvc实现中的Evan的onEnter函数,该函数仅捕获输入函数。
I am trying to create a higher order function to create functions to capture only a specific key code. The code is inspired on Evan's "onEnter" function from his todomvc implementation which captures only the enter function.
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
现在我想将它添加到查看器中的输入组件:
And now I want to add that to an input component in the viewer:
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映射?
If I only have the onEnter the code will work as expected but if I add the onEsc, the onEnter code is never executed. Where am I doing the mistake? is that a problem with the higher order function context or "on" mapping with multiple values in separate functions?
推荐答案
您正在添加输入元素的两个 onkeydown
属性,只有其中一个可以获胜。列表中的第二个将覆盖第一个。如果在幕后使用 addEventListener
,情况并非如此,但现在我们可以用稍微不同的方法来解决它。
You are adding two onkeydown
attributes to the input element, and only one of them can win. The second in the list overwrites the first. Were it to use addEventListener
behind the scenes, this would not be the case, but for now we can solve it with a slightly different approach.
您可以编写一个 onKeysDown
函数,该函数接受可能的密钥代码列表以及他们应该调用的消息,如下所示:
You could write a onKeysDown
function that accepts a list of possible key codes and the message they should invoke like this:
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)
然后你可以编写速记函数来处理这样的特定键:
You could then write shorthand functions for handling specific keys like this:
enter msg = (13, msg)
esc msg = (27, msg)
现在你可以在你的视图中使用它:
And now you can use it in your view like this:
input
[ ...
, onKeysDown
[ enter <| SwitchEditTodo item.uid False
, esc <| UndoEditTodo item.uid
]
]
这有效,因为它生成一个 keydown
事件处理程序属性。当你用一个预定义的元组替换一个更高阶函数时,它仍然会给你一个可读的代码。
This works because it generates a single keydown
event handler attribute. And while you substitute a predefined tuple for a higher order function, it still gives you just as readable code.
这篇关于使用elm高阶函数进行键盘事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!