使用elm高阶函数进行键盘事件 [英] Using elm higher order functions for keyboard events

查看:128
本文介绍了使用elm高阶函数进行键盘事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个更高阶的函数来创建仅捕获特定键代码的函数。该代码的灵感来自于他的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆