2016-12-16 52 views
1

有什么方法可以知道滚动条是否在Elm元素的底部?我使用Dom.Scroll.toBottom在添加列表项时滚动到列表的底部。单独使用时效果很好。但是,如果您手动向上滚动一下,我不想自动向下滚动到底部(直到您再次手动滚动到底部)。否则,您无法查看以前的列表项目。如何知道滚动条是否在元素的底部

+0

是否有不允许使用['Dom.Scroll.y'(HTTP任何问题:// package.elm-lang.org/packages/elm-lang/dom/1.1.1/Dom-Scroll#y)? – lonelyelk

+0

@lonelyelk'Dom.Scroll.y'不足以知道滚动条是否在元素的底部。 'y'只能告诉你滚动的距离(以像素为单位)。不知道底部**有多远,你怎么知道你在底部? –

回答

1

我能用以下代码获得clientHeight,scrollHeightscrollTop属性。那些有必要知道滚动是否在元素的底部。代码的其余部分实现了自动滚动仅机制,如果滚动已经处于底部:

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