Elm 0.17 及更高版本中的键盘组合

Keyboard combinations in Elm 0.17 and later

如何将键盘组合构建到我的 Elm 应用程序中,例如。 "shift + alt + enter"?你会做这样的事情来对按下的单个键做出反应(例如回车键):

import Keyboard

type Msg
  = KeyDown Keyboard.KeyCode

type alias Model =
  ...

update msg model =
    case msg of
        KeyDown key ->
          handleKeyDown key model

subscriptions model =
    Sub.batch
        [ 
          Keyboard.downs KeyDown
        ]

handleKeyDown key model =
  case key of
    13 -> -- Enter key
      Debug.log "Other key"
      model

    _ -> -- Any other key
      Debug.log "Other key"
      model


view model =
    ...

但是你怎么能对按下的多个键做同样的事情呢?

您可以像 pdoherty926 提到的那样使用 Keyboard.downs 以及 Set 来跟踪按下了哪些键。您还需要查看 Keyboard.ups 以了解何时释放密钥。

这是一个工作示例:

import Html exposing (..)
import Html.App exposing (program)
import Keyboard exposing (..)
import Set exposing (Set)
import Char

main =
  program { init = (initialModel, Cmd.none), view = view, update = update, subscriptions = subscriptions }

initialModel =
  { keysDown = Set.empty
  }

view : Model -> Html Msg
view model =
  text <| toString <| Set.map Char.fromCode model.keysDown

type Msg
  = KeyDown KeyCode
  | KeyUp KeyCode

type alias Model =
  { keysDown : Set KeyCode
  }

update msg model =
  case msg of
    KeyDown key ->
      ({ model | keysDown = Set.insert key model.keysDown }, Cmd.none)
    KeyUp key ->
      ({ model | keysDown = Set.remove key model.keysDown }, Cmd.none)

subscriptions _ =
    Sub.batch
        [ Keyboard.downs KeyDown
        , Keyboard.ups KeyUp
        ]

来自the documentation

Longer-term, it makes sense to help track key combinations and a couple other common scenarios. If you have a particular problem you think this library could address more directly, please describe it as a SSCCE in an issue. Please do not suggest the solution. Just describe the scenario. Once it becomes clearer what folks are up to, it will be time to add support for those cases in a coherent way.

所以,至少这意味着它现在不受支持。我不完全确定这是否也意味着你应该打开一个问题来鼓励以后添加。

现在,Chad 的回答对我来说似乎是一个很好的临时解决方案。 swelet 建议只跟踪几个修改键,它看起来更好。请注意,如果采用这种方法,则无需依赖任何 ListSet,而是可以使用 4 个布尔值进行记录。

最后,如果您出于某些原因想要跟踪所有键(例如,如果您希望用户能够 link [F1] 执行某些操作,那么在性能方面它是有意义的使用更有效的集合表示。例如,有限集的任何子集都可以定义为单个数字,每个位都是一个布尔值,表示一个特定元素的存在或不存在。您可以使用 Bitwise图书馆。