My elm application uses an auto-scroll function that gets the Y position of an element and uses Dom.Scroll .toY to scroll there.
Two do this; I configure two ports; subscription and sender.
ports.elm
port setYofElementById : Maybe String -> Cmd msg
port getYofElementById : (Value -> msg) -> Sub msg
index.html
app.ports.setYofElementById.subscribe(function(id) {
var element = document.getElementById(id);
var rect = element.getBoundingClientRect();
app.ports.getYofElementById.send({"number": rect.top});
})
Listener is a subscription
subscriptions : Model -> Sub Msg
subscriptions model =
Ports.getYofElementById getYofElementById
getYofElementById : Decode.Value -> Msg
getYofElementById value =
let
result =
Decode.decodeValue bSimpleIntValueDecoder value
in
case result of
Ok simpleIntValue ->
SetSelectedElementYPosition (Just simpleIntValue.number)
Err id ->
SetSelectedElementYPosition Nothing
SetSelectedElementYPosition
just sets up the model.
Now the action that does this has two functions: call Port.setYofElementById
, then scroll to the Y value in the model, assuming it is already set.
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
ScrollToY idString ->
model
=> Cmd.batch
[ Ports.setYofElementById (Just idString)
, Task.attempt (always NoOp) <| Dom.Scroll.toY "ul" model.selectedElementYPosition
]
However, this does not occur sequentially. When the action first fires, nothing happens. If I run it again, it scrolls to the location specified in the first action. Therefore, it seems that it calls Dom.Scroll.toY
before the value is set.
Cmd
in ScrollToY
? ?