如何在Elm中自动滚动到div的底部

时间:2016-12-09 03:19:30

标签: elm elm-port

我将<div>添加到包装器<div>,我需要能够滚动到每次添加的最后一个。我如何在榆树中做到这一点?

<div class="messages" style="height: 7em; overflow: scroll">
  <div>Anonymous: Hello</div>
  <div>John: Hi</div>
</div>

直观地说,似乎我可以调用运行JavaScript代码port的{​​{1}}:

element.scrollTop = element.scrollHeight

问题是AddChatMessage chatMessage -> ( { model | chatMessages = model.chatMessages ++ [ chatMessage ] } , scrollToBottomPort "div.messages" ) scrollToBottom更新后被称为。没什么大不了的,我把它转换成model。但是,即使Task现在首先更新,model也不会更新。所以我最终滚动到底部的第二个项目!

这可能会导致我对Elm感到好奇的一个更普遍的问题,在视图因模型更改而更新视图后如何运行view

4 个答案:

答案 0 :(得分:7)

您可以使用端口滚动到列表的底部 在这种情况下,您需要在执行滚动之前设置javascript以等待1个AnimationFrame。确保您的列表已呈现。

更简单的方法是使用Elm的Dom.Scroll库 并使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <li><a href="#">Link 1</a></li> <li><a href="#">Link 2</a></li> <li><a href="#">Link 3</a></li> <li><a href="#">Link 4</a></li> <li><a href="#">Link 5</a></li> <li><a href="#">Link 6</a></li> <li><a href="#">Link 7</a></li> <hr align="left" width="100%" color="#a2a2a2"> <hr align="left" width="100%" color="#a2a2a2">函数。

如果您在代码中包含这样的内容:

toBottom

它应该工作。 我做了一个有效的例子here in runelm.io

答案 1 :(得分:3)

从Elm 0.19开始,使用功能Browser.Dom.getViewportOfBrowser.Dom.setViewportOf,每次将新元素添加到容器时,您都可以进入容器的底部。

jumpToBottom : String -> Cmd Msg
jumpToBottom id =
    Dom.getViewportOf id
        |> Task.andThen (\info -> Dom.setViewportOf id 0 info.scene.height)
        |> Task.attempt (\_ -> NoOp)

答案 2 :(得分:1)

Dom.Scroll绝对是最佳选择,并且易于实施。

  1. 设置要滚动的封闭HTML元素以使其具有不同的内容 ID。
  2. 确保所述元素具有溢出样式:滚动或 overflow-x:scroll。
  3. 实际从任何消息发送命令         导致该元素被显示/打开(消息         打开/显示元素,而您触发的命令将执行此操作         滚动)。请注意,您使用命令是因为更改DOM在技术上是一种副作用。
  4. 查看文档说滚动到底部: toBottom : Id -> Task Error (),您可以看到它必须是一个任务,因此您可以将其包含在Task.attempt中。例如: Task.attempt (\_ -> NoOp) (Dom.Scroll.toBottom Id)

    然后您需要一个函数将结果Error()转换为Msg,但由于滚动不太可能失败或者如果它不具有下行作用,您可以设置像(\_ -> NoOp)这样的虚拟函数快速破解。

答案 3 :(得分:0)

因为不建议使用版本0.19 Dom,而是可以使用Html.Attribute.property函数设置滚动位置。

示例

import Html exposing (Html, text)
import Html.Attributes exposing (class, property)
import Json.Encode as Encode


view : Model -> Html Msg
view model =
    div [ class "flow-editor"
        , property "scrollLeft" (Encode.float model.scrollLeft)
        , property "scrollTop" (Encode.float model.scrollTop)
        ]
        [ text "placeholder" ]