使用 jumpToBottom 实现自动滚动
Implementing autoscroll with jumpToBottom
setViewportOf
的文档包含函数 jumpToBottom
。
下面是一个使用它的小示例程序:
module Main exposing (..)
import Browser
import Html exposing (..)
import Html.Events exposing (..)
import Html.Attributes exposing (..)
import Browser.Dom
import Task
type Msg = AddText | NoOp
type alias Model = { messages : List String }
jumpToBottom : String -> Cmd Msg
jumpToBottom id =
Browser.Dom.getViewportOf id
|> Task.andThen (\info -> Browser.Dom.setViewportOf id 0 info.scene.height)
|> Task.attempt (\_ -> NoOp)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
AddText -> ({ model | messages = model.messages ++ [ "abc" ]}, jumpToBottom "messages")
NoOp -> (model, Cmd.none)
view : Model -> Html Msg
view model =
div [ id "outer" ]
[
div [ id "messages" ]
[
ul [] (List.map (\message -> li [] [ text message ]) model.messages)
],
button [ onClick AddText ] [ text "Add" ]
]
init : () -> (Model, Cmd Msg)
init _ = ({ messages = [] }, Cmd.none)
main = Browser.element { init = init, view = view, update = update, subscriptions = (\_ -> Sub.none) }
可以将此程序粘贴到 Try Elm 中进行测试。
每次按下该按钮,文本都会添加到页面中。最终,将添加超出屏幕大小的文本,并出现滚动条。我希望页面自动滚动,但这似乎没有发生。
如果我改变
jumpToBottom "messages"
到
jumpToBottom "outer"
这似乎没有效果。
欢迎提出任何建议! :-)
这是一个 CSS 布局问题。为了更好地理解,将此添加到您的页面 CSS(您可以在 https://ellie-app.com/ 上测试)。
#messages {
max-height: 200px;
overflow-y:auto;
}
以上内容使 messages
成为可以设置其视口的可滚动元素。在没有某种高度限制的情况下,messages
div 将根据需要展开,视口将始终与场景相同,或者换句话说,它永远不会滚动。
以下是基于@pdamoc 建议的版本。
一些差异:
- css 样式是内联的,因此可以将其粘贴到 https://elm-lang.org/try
max-height
不是固定的,所以它会扩展以填充window。
module Main exposing (..)
import Browser
import Html exposing (..)
import Html.Events exposing (..)
import Html.Attributes exposing (..)
import Browser.Dom
import Task
type Msg = AddText | NoOp
type alias Model = { messages : List String }
jumpToBottom : String -> Cmd Msg
jumpToBottom id =
Browser.Dom.getViewportOf id
|> Task.andThen (\info -> Browser.Dom.setViewportOf id 0 info.scene.height)
|> Task.attempt (\_ -> NoOp)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
AddText -> ({ model | messages = model.messages ++ [ "abc" ]}, jumpToBottom "messages")
NoOp -> (model, Cmd.none)
view : Model -> Html Msg
view model =
div
[
class "main",
style "flex-grow" "1",
style "display" "flex",
style "flex-direction" "column",
style "max-height" "100vh"
]
[
div
[
id "messages",
class "messages",
style "flex-grow" "1",
style "padding" "24px 24px 0 24px",
style "overflow-y" "scroll"
]
(List.map (\message -> p [] [ text message ]) model.messages),
button [ onClick AddText ] [ text "Add" ]
]
init : () -> (Model, Cmd Msg)
init _ = ({ messages = [] }, Cmd.none)
main = Browser.element { init = init, view = view, update = update, subscriptions = (\_ -> Sub.none) }
setViewportOf
的文档包含函数 jumpToBottom
。
下面是一个使用它的小示例程序:
module Main exposing (..)
import Browser
import Html exposing (..)
import Html.Events exposing (..)
import Html.Attributes exposing (..)
import Browser.Dom
import Task
type Msg = AddText | NoOp
type alias Model = { messages : List String }
jumpToBottom : String -> Cmd Msg
jumpToBottom id =
Browser.Dom.getViewportOf id
|> Task.andThen (\info -> Browser.Dom.setViewportOf id 0 info.scene.height)
|> Task.attempt (\_ -> NoOp)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
AddText -> ({ model | messages = model.messages ++ [ "abc" ]}, jumpToBottom "messages")
NoOp -> (model, Cmd.none)
view : Model -> Html Msg
view model =
div [ id "outer" ]
[
div [ id "messages" ]
[
ul [] (List.map (\message -> li [] [ text message ]) model.messages)
],
button [ onClick AddText ] [ text "Add" ]
]
init : () -> (Model, Cmd Msg)
init _ = ({ messages = [] }, Cmd.none)
main = Browser.element { init = init, view = view, update = update, subscriptions = (\_ -> Sub.none) }
可以将此程序粘贴到 Try Elm 中进行测试。
每次按下该按钮,文本都会添加到页面中。最终,将添加超出屏幕大小的文本,并出现滚动条。我希望页面自动滚动,但这似乎没有发生。
如果我改变
jumpToBottom "messages"
到
jumpToBottom "outer"
这似乎没有效果。
欢迎提出任何建议! :-)
这是一个 CSS 布局问题。为了更好地理解,将此添加到您的页面 CSS(您可以在 https://ellie-app.com/ 上测试)。
#messages {
max-height: 200px;
overflow-y:auto;
}
以上内容使 messages
成为可以设置其视口的可滚动元素。在没有某种高度限制的情况下,messages
div 将根据需要展开,视口将始终与场景相同,或者换句话说,它永远不会滚动。
以下是基于@pdamoc 建议的版本。
一些差异:
- css 样式是内联的,因此可以将其粘贴到 https://elm-lang.org/try
max-height
不是固定的,所以它会扩展以填充window。
module Main exposing (..)
import Browser
import Html exposing (..)
import Html.Events exposing (..)
import Html.Attributes exposing (..)
import Browser.Dom
import Task
type Msg = AddText | NoOp
type alias Model = { messages : List String }
jumpToBottom : String -> Cmd Msg
jumpToBottom id =
Browser.Dom.getViewportOf id
|> Task.andThen (\info -> Browser.Dom.setViewportOf id 0 info.scene.height)
|> Task.attempt (\_ -> NoOp)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
AddText -> ({ model | messages = model.messages ++ [ "abc" ]}, jumpToBottom "messages")
NoOp -> (model, Cmd.none)
view : Model -> Html Msg
view model =
div
[
class "main",
style "flex-grow" "1",
style "display" "flex",
style "flex-direction" "column",
style "max-height" "100vh"
]
[
div
[
id "messages",
class "messages",
style "flex-grow" "1",
style "padding" "24px 24px 0 24px",
style "overflow-y" "scroll"
]
(List.map (\message -> p [] [ text message ]) model.messages),
button [ onClick AddText ] [ text "Add" ]
]
init : () -> (Model, Cmd Msg)
init _ = ({ messages = [] }, Cmd.none)
main = Browser.element { init = init, view = view, update = update, subscriptions = (\_ -> Sub.none) }