如何知道滚动条是否在元素的底部
How to know if scrollbar is at the bottom of an element
有什么方法可以知道滚动条是否位于 Elm 中元素的底部?添加列表项时,我正在使用 Dom.Scroll.toBottom
滚动到列表底部。单独放置时效果很好。但是如果你手动向上滚动一点,我不想再自动向下滚动到底部(直到你再次手动滚动到底部)。否则您无法查看之前的列表项。
我能够使用以下代码获得 clientHeight
、scrollHeight
和 scrollTop
属性。这些对于知道滚动是否在元素的底部是必要的。其余代码实现仅当滚动已经在底部时自动滚动的机制:
type alias Model =
{ messages : List Message
, autoScrollMessages : Bool
}
type Msg
= NoOp (Result Dom.Error ())
| ReceiveMessage ReceivedMessage
| ScrolledMessages ScrollEvent
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp res ->
( model, Cmd.none )
ReceiveMessage message ->
( { model | messages = model.messages ++ [ message ] } , if model.autoScrollMessages then Task.attempt NoOp (Scroll.toBottom "messages") else Cmd.none )
ScrolledMessages scrollEvent ->
( { model | autoScrollMessages = scrollEvent.scrollPos == scrollEvent.scrollHeight - scrollEvent.visibleHeight }, Cmd.none )
type alias ScrollEvent =
{ scrollHeight : Int
, scrollPos : Int
, visibleHeight : Int
}
onScroll : (ScrollEvent -> msg) -> Html.Attribute msg
onScroll tagger =
Html.Events.on "scroll" (Decode.map tagger onScrollJsonParser)
onScrollJsonParser : Decode.Decoder ScrollEvent
onScrollJsonParser =
Decode.map3 ScrollEvent
(Decode.at ["target", "scrollHeight"] Decode.int)
(Decode.at ["target", "scrollTop"] Decode.int)
(Decode.at ["target", "clientHeight"] Decode.int)
viewMessages : List Message -> Html Msg
viewMessages messages =
ul
[ id "messages"
, onScroll ScrolledMessages
] <| List.map viewMessage messages
有什么方法可以知道滚动条是否位于 Elm 中元素的底部?添加列表项时,我正在使用 Dom.Scroll.toBottom
滚动到列表底部。单独放置时效果很好。但是如果你手动向上滚动一点,我不想再自动向下滚动到底部(直到你再次手动滚动到底部)。否则您无法查看之前的列表项。
我能够使用以下代码获得 clientHeight
、scrollHeight
和 scrollTop
属性。这些对于知道滚动是否在元素的底部是必要的。其余代码实现仅当滚动已经在底部时自动滚动的机制:
type alias Model =
{ messages : List Message
, autoScrollMessages : Bool
}
type Msg
= NoOp (Result Dom.Error ())
| ReceiveMessage ReceivedMessage
| ScrolledMessages ScrollEvent
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp res ->
( model, Cmd.none )
ReceiveMessage message ->
( { model | messages = model.messages ++ [ message ] } , if model.autoScrollMessages then Task.attempt NoOp (Scroll.toBottom "messages") else Cmd.none )
ScrolledMessages scrollEvent ->
( { model | autoScrollMessages = scrollEvent.scrollPos == scrollEvent.scrollHeight - scrollEvent.visibleHeight }, Cmd.none )
type alias ScrollEvent =
{ scrollHeight : Int
, scrollPos : Int
, visibleHeight : Int
}
onScroll : (ScrollEvent -> msg) -> Html.Attribute msg
onScroll tagger =
Html.Events.on "scroll" (Decode.map tagger onScrollJsonParser)
onScrollJsonParser : Decode.Decoder ScrollEvent
onScrollJsonParser =
Decode.map3 ScrollEvent
(Decode.at ["target", "scrollHeight"] Decode.int)
(Decode.at ["target", "scrollTop"] Decode.int)
(Decode.at ["target", "clientHeight"] Decode.int)
viewMessages : List Message -> Html Msg
viewMessages messages =
ul
[ id "messages"
, onScroll ScrolledMessages
] <| List.map viewMessage messages