在Elm中,我如何检测焦点是否会从一组元素中丢失?

z5h*_*z5h 4 events json dom elm

假设我有一个包含许多组件的表单.我想从小组中发现一个焦点.因此,应忽略在同一表单上从1输入到另一个输入的焦点.我怎样才能做到这一点?

z5h*_*z5h 8

首先,我们希望能够用一些属性标记组内的每个可聚焦元素,因此当我们切换元素时,我们将知道我们是否在同一组中.这可以通过数据属性来实现.

groupIdAttribute groupId =
    Html.Attributes.attribute "data-group-id" groupId
Run Code Online (Sandbox Code Playgroud)

接下来,我们需要解码事件上的事件有效负载,onBlur以查看它是否targetrelatedTarget(将获得焦点)不同.并报告变化.(注意,这里我们data-group-id通过路径引用"dataset", "groupId")

decodeGroupIdChanged msg =
    Json.Decode.oneOf
        [ Json.Decode.map2
            (\a b ->
                if a /= b then
                    Just a

                else
                    Nothing
            )
            (Json.Decode.at [ "target", "dataset", "groupId" ] Json.Decode.string)
            (Json.Decode.at [ "relatedTarget", "dataset", "groupId" ] Json.Decode.string)
        , Json.Decode.at [ "target", "dataset", "groupId" ] Json.Decode.string
            |> Json.Decode.andThen (\a -> Json.Decode.succeed (Just a))
        ]
        |> Json.Decode.andThen
            (\maybeChanged ->
                case maybeChanged of
                    Just a ->
                        Json.Decode.succeed (msg a)

                    Nothing ->
                        Json.Decode.fail "no change"
            ) 
Run Code Online (Sandbox Code Playgroud)

现在我们可以创建一个onGroupLoss监听器:

onGroupFocusLoss msg =
    Html.Events.on "blur" (decodeGroupIdChanged msg)
Run Code Online (Sandbox Code Playgroud)

并按照这样的方式进行操作:

input [onGroupFocusLoss GroupFocusLoss, groupIdAttribute "a"]
Run Code Online (Sandbox Code Playgroud)

这是一个例子(注意它是用elm-ui构建的,所以有一些额外的代码.)

https://ellie-app.com/3nkBCXJqjQTa1

  • 您可以在祖先上使用`focusout`处理程序,而不是在每个输入上附加`blur`处理程序. (2认同)