marc walter

Mouse scroll events in Elm (using JSON decoders)

2018-03-29 (Last updated on 2018-09-01)

Handling scroll events in Elm is not perfect, but on the elm discourse channel the user @ilias pointed out a nice way:

In Elm 0.18 and 0.19:

Use a port to send wheel events from JavaScript to the Elm app

const app = Elm.Main.init({ node: document.querySelector('main') })
document.addEventListener("wheel", app.ports.onWheel.send);

and decode them into an Elm Msg type

type Msg
    = NoOp
    | Wheel { deltaX : Float, deltaY : Float }

port onWheel : (Json.Decode.Value -> msg) -> Sub msg

subscriptions : model -> Sub Msg
subscriptions _ =
    onWheel Wheel
        (\val ->
            case Decode.decodeValue wheelDecoder val of
                Ok model ->
                    Wheel model

                Err _ ->
                    NoOp
        )

wheelDecoder : Json.Decoder Model
wheelDecoder =
    Json.Decode.map2 Model
        (Json.Decode.field "deltaX" Decode.float)
        (Json.Decode.field "deltaY" Decode.float)

...

In the future

Remove the port, and use the new onWindow or onDocument functions:

subscriptions : model -> Sub Msg
subscriptions _ =
    onDocument "wheel" (Json.Decode.map Wheel wheelDecoder)

This was proposed for Elm 0.19, but unfortunately it did not make it into the final release.